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)
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})
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})
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 })
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)
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
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})
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})
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})
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
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)
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})
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})
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})
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})
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})
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})
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
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
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
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})
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})
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
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})
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})
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
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
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
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
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})