Esempio n. 1
0
 def get(self, request):
     """生成QQ登录的地址"""
     state = request.query_params.get('state')  # 客户端指定的状态
     oauth = OAuthQQ(state=state)
     url = oauth.get_auth_url()
     print(url)
     return Response(url)
Esempio n. 2
0
    def get(self, request):
        # 提供qq登录的url
        next = request.query_params.get('next')
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_qq_login_url()

        return Response({'login_url': login_url})
Esempio n. 3
0
    def get(self, request):
        next = request.query_params.get('next', '/')
        # 获取qq登录url地址
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_login_url()

        return Response({'login_url': login_url})
Esempio n. 4
0
    def get(self, request):
        code = request.query_params.get('code')

        if not code:
            return Response({'message': '缺少code'},
                            status=status.HTTP_400_BAD_REQUEST)
        oauth_qq = OAuthQQ()
        try:
            access_token = oauth_qq.get_access_token(code)
            openid = oauth_qq.get_openid(access_token)

        except OAuthQQAPIError:
            return Response({'message': '访问QQ接口异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        try:
            oauth_qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果数据不存在,处理openid 并返回
            access_token = oauth_qq.generate_bind_user_access_token(openid)
            return Response({'access_token': access_token})
        else:

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            user = oauth_qq_user.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            return Response({
                'username': user.username,
                'user_id': user.id,
                'token': token
            })
Esempio n. 5
0
    def get(self, request):
        #step1: 获取code并效验
        code = request.query_params.get('code')
        if code is None:
            return ActionResult.failure(status.HTTP_400_BAD_REQUEST,
                                        '缺少code参数')

        #step2: 根据code获取QQ 登录的openid
        oauth = OAuthQQ()
        try:
            #2.1通过code请求QQ服务器获取access_token
            access_token = oauth.get_access_token(code)
            #2.2通过access_token请求QQ服务器获取openid
            openid = oauth.get_openid(access_token)
        except QQAPIError:
            return ActionResult.failure(status.HTTP_503_SERVICE_UNAVAILABLE,
                                        'QQ登录异常')
        #step3: 根据openid判断是否绑定过本站点的用户
        try:
            qq_user_obj = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            #3.2如果未绑定,将openid加密并返回
            secret_openid = OAuthQQ.generate_save_user_token(openid)
            return ActionResult.success({'access_token': secret_openid})
        else:
            #返回jwt_token
            user = qq_user_obj.user
            token = response_jwt_payload_token(qq_user_obj.user)

            data = {
                'user_id': user.id,
                'username': user.username,
                'token': token
            }
            return ActionResult.success(data)
Esempio n. 6
0
    def get(self, request):
        """
        获取QQ登录用户的openid并处理:
        1. 获取code并校验(code必传)
        2. 获取QQ登录用户openid
            2.1 根据code请求qq服务器获取access_token
            2.2 根据access_token请求qq服务器获取openid
        3. 根据openid判断是否绑定过本网站用户
            3.1 如果已绑定,直接生成jwt token并返回
            3.2 如果未绑定,将openid加密并返回
        """
        # 1. 获取code并校验(code必传)
        code = request.query_params.get('code')

        if code is None:
            return Response({'message': '缺少code参数'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 2. 获取QQ登录用户openid
        oauth = OAuthQQ()
        try:
            # 2.1 根据code请求qq服务器获取access_token
            access_token = oauth.get_access_token(code)
            # 2.2 根据access_token请求qq服务器获取openid
            openid = oauth.get_openid(access_token)
        except QQAPIError:
            return Response({'message': 'QQ登录异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 3. 根据openid判断是否绑定过本网站用户
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 3.2 如果未绑定,将openid加密并返回
            secret_openid = oauth.generate_save_user_token(openid)
            return Response({'access_token': secret_openid})
        else:
            # 3.1 如果已绑定,直接生成jwt token并返回
            from rest_framework_jwt.settings import api_settings

            user = qq_user.user
            # 生成载荷的内容
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            # 生成jwt token
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            # 返回响应
            response_data = {
                'user_id': user.id,
                'username': user.username,
                'token': token
            }

            # 调用合并购物车记录函数
            response = Response(response_data)
            merge_cookie_cart_to_redis(request, user, response)
            return response
Esempio n. 7
0
 def get(self, request):
     """获取qq登录的地址"""
     next = request.query_params.get('next', '/')
     oauth = OAuthQQ(state=next)
     # 前端请求该地址,获取授权
     login_url = oauth.get_login_url()
     return Response({'login_url': login_url})
Esempio n. 8
0
	def get(self, request):
		"""
		:return 扫码的url地址
		"""
		state = request.query_params.get('state')
		oauthqq = OAuthQQ(state=state)
		qq_login_url = oauthqq.generate_qq_login_url()
		return Response({'qq_login_url': qq_login_url})
Esempio n. 9
0
    def get(self, request):
        """GET /oauth/qq/authorization/?next=/user_center_info.html"""
        next = request.query_params.get("next")
        # 拼接QQ登录的url
        oauth_qq = OAuthQQ(state=next)
        login_url = oauth_qq.get_login_url()

        return Response({"login_url": login_url})
Esempio n. 10
0
    def get(self, request):
        """
        接收:code,是qq返回的授权凭证code
        返回:access_token:用户第一次使用QQ登录时需要返回,包含openid,用于跳转到绑定身份界面
                            通过itsdangerous生成access_token
            token:用户不是第一次使用QQ登录时需要返回,通过JWTtoken
            username & user_id:用户不是第一次使用QQ登录时返回
        """
        # 取参
        code = request.query_params.get("code")
        # 校参
        if not code:
            return Response({"message": "缺少code"},
                            status=status.HTTP_400_BAD_REQUEST)
        # 实例化QQ认证辅助工具类:
        oauth_qq = OAuthQQ()
        try:
            # 通过code获取access_token
            access_token = oauth_qq.get_access_token(code)
            # 通过access_token获取openid
            openid = oauth_qq.get_openid(access_token)
        except OAuthQQAPIError:
            return Response({"message": "访问QQ接口获取access_token/openid异常"},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 此时已经获取了openid;接下来从数据库读取qq用户openid数据
        try:
            oauth_qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果qq用户数据不存在,则通过openid生成假的access_token并返回
            # 方法内部使用isdangerous
            access_token = oauth_qq.generate_bind_user_access_token(openid)
            return Response({"access_token": access_token})
        else:
            # 尝试查询成功,表明用户已经绑定过身份,则签发jwt token
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            # 通过三方表的外键获取当前用户对象
            user = oauth_qq_user.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            # 响应数据:登录注册都一样:
            #   以下数据将在Response中放在第一个参数data中,前端通过request.data获取数据
            # return Response({
            #     "username": user.username,
            #     "user_id": user.id,
            #     "token": token
            # })
            # 已绑定用户:返回response前,调用合并购物车数据的公共方法,并接受返回值作为response
            response = Response({
                "username": user.username,
                "user_id": user.id,
                "token": token
            })
            response = merge_cart_cookie_to_redis(request, user, response)

            return response
Esempio n. 11
0
    def get(self, request):
        """
        获取QQ登陆用户的openid并进行校验
        1. 获取code并进行校验(code必传)
        2. 获取QQ登陆用户的openid
            2.1 根据code请求QQ服务器获取access_token
            2.2 根据access_token请求QQ服务器获得openid
        3. 根据openid进行处理
            3.1 如果openid已经绑定过本网站用户,直接签发jwt token并返回
            3.2 如果openid未绑定过本网站用户,对openid进行加密,返回加密之后的内容
        """
        # 1. 获取code并进行校验(code必传)
        code = request.query_params.get('code')  # None

        if code is None:
            return Response({'message': '缺少code参数'}, status=status.HTTP_400_BAD_REQUEST)

        # 2. 获取QQ登陆用户的openid
        oauth = OAuthQQ()

        try:
            # 2.1 根据code请求QQ服务器获取access_token
            access_token = oauth.get_access_token(code)
            # 2.2 根据access_token请求QQ服务器获得openid
            openid = oauth.get_openid(access_token)
        except QQAPIError:
            return Response({'message': 'QQ登陆服务异常'},status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 3. 根据openid进行处理
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 3.2 如果openid未绑定过本网站用户,对openid进行加密,返回加密之后的内容
            access_token = OAuthQQ.generate_save_user_token(openid)
            return Response({'access_token': access_token})
        else:
            # 3.1 如果openid已经绑定过本网站用户,直接签发jwt token并返回
            user = qq_user.user

            # 有服务器生成一个jwt token数据,包含登陆用户身份信息
            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            # 生成载荷
            payload = jwt_payload_handler(user)
            # 生成jwt token
            token = jwt_encode_handler(payload)

            # 返回响应
            resp_data = {
                'user_id': user.id,
                'username': user.username,
                'token': token
            }
            return Response(resp_data)
Esempio n. 12
0
 def get(self, request):
     """
     提供qq登录的url
     :param request:
     :return:
     """
     next = request.query_params.get("next")
     oauth = OAuthQQ(state=next)
     login_url = oauth.get_qq_login_url()
     return Response({'login_url': login_url})
Esempio n. 13
0
    def get(self, request):
        # 获取next参数
        next = request.query_params.get('next')

        # 拼接QQ登录的网址
        oauth_qq = OAuthQQ(state=next)
        login_url = oauth_qq.get_login_url()
        # print(login_url)

        # 返回
        return Response({'login_url': login_url})
Esempio n. 14
0
 def get(self, request):
     """
     用户qq登陆的url
     :param request:
     :return:
     """
     # 获取参数
     next = request.query_params.get('next')
     oauth = OAuthQQ(state=next)
     login_url = oauth.get_qq_login_url()
     return Response({'login_url': login_url})
Esempio n. 15
0
    def get(self, request):
        # 1.获取next参数
        next = request.query_params.get("next")

        # 2.拼接qq登录的网址
        # 从自定义类中获取qq认证页面的url
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_qq_login_url()

        # 3.返回login_url: https://graph.qq.com/oauth2.0/authorize?next=/  如:user_center_info.js
        return Response({"login_url": login_url})
Esempio n. 16
0
    def get(self, request):
        """提供用于qq登录的url"""
        # 获取next参数
        next = request.query_params.get('next')

        # 拼接qq登录的网址
        oauth_qq = OAuthQQ(state=next)
        login_url = oauth_qq.get_login_url()
        # print("login_url: %s" % login_url)

        return Response({'login_url': login_url})
Esempio n. 17
0
    def get(self, request):
        state = request.query_params.get('state')

        # 生成qq对象调用方法
        oauth = OAuthQQ(state=state)

        # 获取qq登录url

        # 为请求加上必须的信息! 返回的是 qq提供的地址!
        login_url = oauth.get_qq_login_url()

        return Response({'login_url': login_url})
Esempio n. 18
0
    def get(self, request):
        # 获取code
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 通过工具获取access_token
        oauth_qq = OAuthQQ()
        try:
            # 凭借code 获取access_token
            access_token = oauth_qq.get_access_token(code)

            # 凭借access_token获取 openid
            openid = oauth_qq.get_openid(access_token)

        except OAuthQQAPIError:
            return Response({'message': '访问QQ接口异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 根据openid查询数据库OAuthQQUser  判断数据是否存在
        try:
            oauth_qq_user = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:
            # 如果数据不存在,处理openid  要求用户绑定并注册 , 返回
            access_token = OAuthQQ.generate_bind_user_access_token(openid)
            return Response({'access_token': access_token})
        else:
            # 如果数据存在,表示用户已经绑定过身份, 签发JWT token
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            # 签发的时候,要向 jwt_payload_handler 传递 user对象
            user = oauth_qq_user.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

        # return Response({
        #     'token': token,
        #     'username': user.username,
        #     'user_id': user.id
        # })
        response = Response({
            'token': token,
            'username': user.username,
            'user_id': user.id
        })

        # 合并购物车
        merge_cart_cookie_to_redis(request, user, response)

        return response
Esempio n. 19
0
    def get(self, request):
        """
        获取qq登录的用户数据
        :param request:
        :return:
        """
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'},
                            status=status.HTTP_400_BAD_REQUEST)

        oauth = OAuthQQ()

        # 获取用户的openid
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_openid(access_token)
        except QQAPIError:
            return Response({'message': 'QQ服务异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 判断用户是否存在
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 用户第一次使用QQ登录;
            token = oauth.generate_save_user_token(openid)
            return Response({'access_token': token})
        else:
            # 找到用户,生成token
            user = qq_user.user
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            # return Response({
            #     'token':token,
            #     'user_id':user.id,
            #     'username':user.username
            # })

            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })
            # 合并购物车
            response = merge_cart_cookie_to_redis(request, user, response)
            return response
Esempio n. 20
0
    def get(self, request):
        """
        GET /oauth/qq/user/?code=xxx
        :param request:
        :return:
        1. 如果用户是第一次使用QQ登录,返回access_token(包含openid)
        2. 如果用户不是第一次使用QQ登录,返回JWT token, username, user_id
        """
        code = request.query_params.get("code")

        if not code:
            return Response({"message": "缺少code"},
                            status=status.HTTP_400_BAD_REQUEST)

        oauth_qq = OAuthQQ()

        try:
            # 通过授权的code获取access_token(开发者身份标识)
            access_token = oauth_qq.get_access_token(code)
            # 通过access_token获取openid(用户唯一身份标识)
            openid = oauth_qq.get_openid(access_token)
        except OAuthQQAPIError:
            return Response({'message': '访问QQ接口异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 根据openid查询数据库OAuthQQUser,判断用户是否存在
        try:
            oauth_qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 用户不存在,说明之前没有注册过,把openid加密成JWT然后直接返回,要求用户填写资料注册账号
            access_token = oauth_qq.generate_bind_user_access_token(openid)
            return Response({"access_token": access_token})
        else:
            # 用户存在,表示QQ已经绑定过本网站账号,直接签发JWT返回
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            user = oauth_qq_user.user  # 用户模型对象取出user字段信息
            payload = jwt_payload_handler(user)  # 放入载荷中
            token = jwt_encode_handler(payload)  # 生成JWT Token

            response = Response({
                "username": user.username,
                "user_id": user.id,
                "token": token
            })
            # 合并购物车
            response = merge_cart_cookie_to_redis(request, user, response)

            return response
Esempio n. 21
0
 def get(self,request):
     """
     获取QQ登录网址
     1.获取next(可以不传)
     2.阻止qq登录网址和参数
     3.返回qq登录网站
     """
     # 1.获取next(可以不传)
     next = request.query_params.get('next','/')
     # 2.阻止qq登录网址和参数
     oauth = OAuthQQ(state=next)
     login_url = oauth.get_login_url()
     # 3.返回qq登录网站
     return Response({'login_url':login_url})
Esempio n. 22
0
    def get(self, request):
        """
        获取QQ登录网址:
        1. 获取next
        2. 组织QQ登录网址和参数
        3. 返回QQ登录网址
        """
        # 1. 获取next
        next = request.query_params.get('next', '/')

        # 2. 组织QQ登录网址和参数
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_login_url()
        # 3. 返回QQ登录网址
        return ActionResult.success({'login_url': login_url})
Esempio n. 23
0
    def validate(self, attrs):
        access_token = attrs['access_token']
        openid = OAuthQQ.check_save_user_token(access_token)
        if not openid:
            raise serializers.ValidationError("无效的access_token")

        attrs['openid'] = openid

        mobile = attrs['mobile']
        sms_code = attrs['sms_code']
        redis_conn = get_redis_connection('verify_codes')
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError('短信验证码错误')

        password = attrs['password']
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            pass
        else:
            if not user.check_password(password):
                raise serializers.ValidationError('密码错误')
            attrs['user'] = user

        return attrs
Esempio n. 24
0
    def get(self, request):
        """
        获取QQ登录网址
        1.获取next
        2.组织QQ登录网址和参数
        3.返回QQ登录网址
        """
        # 1.获取next
        next = request.query_params.get('next', '/')

        # 2.组织QQ登录网址和参数
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_login_url()

        # 3.返回QQ登录网址
        return Response({'login_url': login_url})
Esempio n. 25
0
    def get(self, request):
        """
        获取QQ登录网址:
        1. 获取参数next
        2. 组织QQ登录url地址和参数
        3. 返回QQ登录网址
        """
        # 1. 获取参数next
        next = request.query_params.get('next', '/')

        # 2. 组织QQ登录url地址和参数
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_login_url()

        # 3. 返回QQ登录网址
        return Response({'login_url': login_url})
Esempio n. 26
0
    def validate(self, attrs):
        # 校验access_token
        access_token = attrs["access_token"]
        openid = OAuthQQ.check_bind_user_access_token(access_token)
        if not openid:
            return serializers.ValidationError("无效的")

        # 将openid保存到atters中
        attrs["openid"] = openid

        # 校验短信验证码
        mobile = attrs["mobile"]
        sms_code = attrs["sms_code"]
        redis_conn = get_redis_connection("verify_codes")
        real_sms_code = redis_conn.get("sms_%s" % mobile)
        if sms_code != real_sms_code.decode():
            raise serializers.ValidationError("短信验证码错误")

        # 判断用户是否存在,若存在校验密码
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            pass
        else:
            password = attrs["password"]
            if not user.check_password(password):
                raise serializers.ValidationError("密码错误")

            attrs["user"] = user
        return attrs
Esempio n. 27
0
    def validate(self, attrs):
        """校验access_token和短信验证码"""
        access_token = attrs["access_token"]
        # 校验access_token是否被篡改,取出用户在QQ上的openid
        openid = OAuthQQ.check_bind_user_access_token(access_token)
        if not openid:
            raise serializers.ValidationError("无效的access_token")
        attrs["openid"] = openid  # 保存到attrs中,验证通过后传递给validated_data

        # 校验短信验证码
        mobile = attrs["mobile"]
        sms_code = attrs["sms_code"]
        redis_conn = get_redis_connection("verify_codes")
        real_sms_code = redis_conn.get("sms_%s" % mobile)
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError("短信验证码错误")

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            logger.error("用户不存在:%s" % e)
        else:
            # 如果用户存在,校验密码
            password = attrs["password"]
            # 把用户输入的原始明文密码与数据库保存的加密后密码进行对比
            if not user.check_password(password):
                raise serializers.ValidationError("密码错误")
            # 密码一致,把用户模型保存到attrs中记录,以便在validated_data可以取出
            attrs["user"] = user

        return attrs
Esempio n. 28
0
 def validate(self, attrs):
     # attrs 应该是指所有的 fields中的字段
     # 检验access_token
     access_token = attrs['access_token']
     openid = OAuthQQ.check_bind_user_access_token(access_token)
     if not openid:
         raise serializers.ValidationError('无效的access_token')
     attrs['openid'] = openid
     # 检验短信验证码
     mobile = attrs['mobile']
     sms_code = attrs['sms_code']
     redis_conn = get_redis_connection('verify_codes')
     real_sms_code = redis_conn.get('sms_%s' % mobile)
     if real_sms_code.decode() != sms_code:
         raise serializers.ValidationError('短信验证码错误')
     # 如果用户存在,检查用户密码
     try:
         user = User.objects.get(mobile=mobile)
     except User.DoesNotExist:
         pass
     else:
         password = attrs['password']
         if not user.check_password(password):
             raise serializers.ValidationError('密码错误')
         attrs['user'] = user
     return attrs
Esempio n. 29
0
    def validate(self, data):
        # 检验access_token
        access_token = data['access_token']
        openid = OAuthQQ.check_save_user_token(access_token)
        if not openid:
            raise serializers.ValidationError('无效的access_token')

        data['openid'] = openid

        # 检验短信验证码
        mobile = data['mobile']
        sms_code = data['sms_code']
        redis_conn = get_redis_connection('verify_codes')
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError('短信验证码错误')

        # 如果用户存在
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            pass
        else:
            password = data['password']
            if not user.check_password(password):
                raise serializers.ValidationError('密码错误')
            data['user'] = user
        return data
Esempio n. 30
0
    def get(self, request):
        """
        获取QQ登陆网址
        1. 获取next参数
        2. 组织QQ登陆的网址和参数
        3. 返回QQ登陆网址
        """
        # 1. 获取next参数
        next = request.query_params.get('next', '/')  # None

        # 2.组织QQ登陆的网址和参数
        oauth = OAuthQQ(state=next)
        login_url = oauth.get_login_url()

        # 3.返回QQ登陆网址
        return Response({'login_url': login_url})