def get(self, request, username): """ 获取指定用户是否存在,查看用户名在数据库数量,大于0说明有 """ # 核对验证码 text = request.query_params.get('text') image_code_id = request.query_params.get('image_code_id') # 查询redis验证码 redis_conn = get_redis_connection('image') redis_text = redis_conn.get('ImageCode_' + image_code_id).decode() if redis_text != text: return Response({"message": "验证码错误"}, status=status.HTTP_400_BAD_REQUEST) user = User.objects.get(username=username) if not user: return Response(status=status.HTTP_404_NOT_FOUND) # 补充生成记录登录状态的token mobile = user.mobile token = generate_save_user_token(mobile) mobile = mobile.replace(mobile[3:7], '****') data = { "access_token": token, "mobile": mobile } response = Response(data=data) return response
def get(self, request): # 1.获取前端传入的code code = request.query_params.get('code') if not code: return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST) # 2.创建QQ登录工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) # 不需要next参数 try: # 3.调用它里面get_access_token(code) 用code响应QQ服务器获取access_token access_token = oauth.get_access_token(code) # 4.调用它里面get_open_id(access_token) 用access_token响应QQ服务器获取openid openid = oauth.get_open_id(access_token) except Exception as e: # 捕获其他异常 logging.info(e) # 输出到终端和日志文件中 return Response({'message': 'QQ服务器不可用'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 5.查询数据库有没有这个openid try: authQQUserModel = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 6.如果没有这个openid,没有绑定用户,把openid加密之后响应给前端,让前端先暂存一会,等待绑定时使用 # access_token是由于前端写错了,本应该是openid # 没有绑定openid,无法识别用户,不能使用服务器资源,所以只能将openid传给前端,让前端保存 # 因为openid是QQ用户的唯一身份标志,直接传前端可见,需要进行加密传输 access_token_openid = generate_save_user_token(openid) return Response({'access_token': access_token_openid}) else: # 7.如果有这个openid,直接代码登录成功,给前端返回JWT状态保存信息 # 获取到openid 关联的user user = authQQUserModel.user # 通过外键获取user模型对象 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER # 引用jwt中的叫jwt_payload_handler函数(生成payload) jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 函数引用,生成jwt payload = jwt_payload_handler(user) # 根据user生成用户相关的载荷 token = jwt_encode_handler(payload) # 传入载荷生成完整的jwt # 响应对象 response = Response({ 'token': token, 'username': user.username, 'user_id': user.user_id }) # 调用合并购物车函数 # response是个对象,对象是一个可变类型,对它进行改变,它原本就发生了变化,不需要再进行返回 merge_cart_cookie_to_redis(request, user, response) return response
def get(self, request): """提取code请求参数""" code = request.query_params.get('code') if not code: return Response({'message': '缺少code的值'}, status=status.HTTP_400_BAD_REQUEST) # 1.1 创建qq登录工具对象 oauthqq = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 2.通过code向QQ服务器请求获取access_token access_token = oauthqq.get_access_token(code) # 3.通过access_token向QQ服务器请求获取openid openid = oauthqq.get_open_id(access_token) except Exception as e: logger.info(e) return Response({'message': 'QQ服务器异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 4.查询openid是否绑定过美多商城中的用户 try: qqauth_model = QQAuthUser.objects.get(openid=openid) except QQAuthUser.DoesNotExist: # 如果qqauth_model异常,说明用户没有进行过QQ登录, # 如果openid没有绑定过美多商城中的用户 # 把openid进行加密安全处理,再响应给浏览器,让它先帮我们保存一会 openid_save = generate_save_user_token(openid) return Response({'access_token': openid_save}) else: # 如果openid已经绑定过美多商城中的用户(生成jwt token直接让它登录成功) # 手动生成token # QQ登录的状态保持 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER # 加载生成载荷函数 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 加载生成token函数 user = qqauth_model.user # 通过第三方QQ的数据的用户获取user(user是外键,可以得到User) payload = jwt_payload_handler(user) # 生成载荷 token = jwt_encode_handler(payload) # 根据载荷生成token # 返回值 response = Response({ 'token': token, 'username': user.username, 'user_id': user.id, }) # 做cookie购物车合并到redis操作 merge_cart_cookie_to_redis(request, user, response) return response
def get(self, request): # 提取code请求参数 # 使用code向QQ服务器请求access_token # 使用access_token向QQ服务器请求openid # 使用openid查询该QQ用户是否在美多商城中绑定过用户 # 如果openid没绑定美多商城用户,创建用户并绑定到openid # 如果openid已绑定美多商城用户,直接生成JWT token,并返回 # 提取code请求参数 code = request.query_params.get('code') if not code: return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST) # 创建OAuthQQ对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code向QQ服务器请求access_token access_token = oauth.get_access_token(code) # 使用access_token向QQ服务器请求openid openid = oauth.get_open_id(access_token) except Exception as e: logger.info(e) return Response({'message': 'QQ服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 使用openid查询该QQ用户是否在美多商城中绑定过用户 try: oauthqquser_model = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 如果openid没绑定美多商城用户,创建用户并绑定到openid # 为了能够在后续的绑定用户操作中前端可以使用openid,在这里将openid签名后响应给前端 access_token_openid = generate_save_user_token(openid) return Response({'access_token': access_token_openid}) else: # 如果openid已绑定美多商城用户,直接生成JWT token,并返回 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 获取oauth_user关联的user user = oauthqquser_model.user payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return Response({ 'token': token, 'user_id': user.id, 'username': user.username })
def get(self, request): # 获取前端传入的code code = request.query_params.get('code') if not code: # 没有获取到code return Response({"message": "缺少code"}, status=status.HTTP_400_BAD_REQUEST) # 创建qq登录工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 调用get_access_token()方法 用code向qq服务器发请求获得access_token # 从后端发请求 不存在跨域(因为是浏览器的同源策略) access_token = oauth.get_access_token(code) # 调用get_open_id()方法 用code向服务器发请求获得openid openid = oauth.get_open_id(access_token) except Exception as e: logger.info(e) return Response({"message": "QQ服务器不可用"}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 查询数据库有没有这个openid try: oauthqqmodel = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 没有查到openid 创建一个新用户与openid绑定 # OAuthQQUser.objects.create() #调用函数 openid = generate_save_user_token(openid) # 加密后的openid return Response({'access_token': openid}) # 响应给前端 前端名称写错了 加密响应给前端 让前端暂存一会绑定时再使用 else: #查询到了openid 那么直接登录成功 给前端返回jwt user = oauthqqmodel.user # 外键关联的用户对象 # 手动生成token jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER # 生成payload函数的引用 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 生成JWT payload = jwt_payload_handler( user) # 根据user生成用户的载荷部分(字典) 传用户对象过去生成对应的payload token = jwt_encode_handler(payload) # 传入载荷生成完整的jwt return Response({ 'token': token, 'username': user.username, 'user_id': user.id })
def get(self, request, username): # 获取参数 image_code = request.query_params.get('text') image_code_id = request.query_params.get('image_code_id') try: user = User.objects.filter(Q(username=username) | Q(mobile=username)).first() except User.DoesNotExist: return Response({'message': '查询用户对象异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if not user: return Response({'message': '此账户不存在'}, status=status.HTTP_404_NOT_FOUND) # 建立Redis连接对象并校验图片验证码 redis_conn = get_redis_connection('verify_codes') try: real_image_code = redis_conn.get('CODEID_' + image_code_id) except Exception: return Response({'message': '获取真实的图片验证码异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if not real_image_code: return Response({'message': '图片验证码过期了'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: try: redis_conn.delete('CODEID_' + image_code_id) except Exception: return Response({'message': '删除图片验证码异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if image_code.lower() != real_image_code.decode().lower(): return Response({'message': '图片验证码填写错误'}, status=status.HTTP_400_BAD_REQUEST) # 构造字典,响应mobile和access_token # 使用itdangerous生成access_token返回给前端(有效期10分钟) access_token = generate_save_user_token(user.mobile) mobile = user.mobile[:3] + '****' + user.mobile[-4:] data = { 'mobile': mobile, 'access_token': access_token } return Response(data)
def get(self, request): code = request.query_params.get('code') if not code: return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST) oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: access_token = oauth.get_access_token(code) openid = oauth.get_open_id(access_token) except Exception: return Response({'message': 'QQ服务器异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 使用openid查询该qq用户是否在美多商城中绑定过用户 try: qqauth_model = QQAuthUser.objects.get(openid=openid) except QQAuthUser.DoesNotExist: # 如果openid没有绑定过美多商城中的用户 # 把openid进行加密安全处理,再响应给浏览器,让它先帮我们保存一会 openid_sin = generate_save_user_token(openid) return Response({'access_token': openid_sin}) else: # 如果openid已经绑定过美多商城中的用户(生成jwt token直接让它登录成功) # 手动生成token jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER # 加载生成载荷函数 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 加载生成token函数 # 获取user对象 user = qqauth_model.user payload = jwt_payload_handler(user) # 生成载荷 token = jwt_encode_handler(payload) # 根据载荷生成token response = Response({ 'token': token, 'username': user.username, 'user_id': user.id }) # 做cookie购物车合并到redis操作 merge_cart_cookie_to_redis(request, user, response) return response
def get(self, request, username): # 获取参数 sms_code = request.query_params.get('sms_code') try: # TODO: 可以通过之前加密过的access_token取出mobile进行验证,避免恶意用户伪造请求 user = User.objects.filter(Q(username=username) | Q(mobile=username)).first() except User.DoesNotExist: return Response({'message': '查询用户对象异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if not user: return Response({'message': '此账户不存在'}, status=status.HTTP_404_NOT_FOUND) # 建立Redis连接对象并校验短信验证码 redis_conn = get_redis_connection('verify_codes') try: real_sms_code = redis_conn.get('SMSCODE_%s' % user.mobile) except Exception: return Response({'message': '获取真实的图片验证码异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if not real_sms_code: return Response({'message': '图片验证码过期了'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: try: redis_conn.delete('SMSCODE_%s' % user.mobile) except Exception: return Response({'message': '删除图片验证码异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if sms_code != real_sms_code.decode(): return Response({'message': '图片验证码填写错误'}, status=status.HTTP_400_BAD_REQUEST) # 构造字典,响应mobile和access_token # 使用itdangerous生成access_token返回给前端(有效期10分钟) access_token = generate_save_user_token(user.mobile) data = { 'user_id': user.id, 'access_token': access_token } return Response(data)
def get(self, request): # 获取code code = request.query_params.get('code') if not code: return Response({'message': "缺少授权码"}, status=status.HTTP_400_BAD_REQUEST) oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URL, state=next) # 获取access_token access_token = oauth.get_access_token(code) # 获取openid openId = oauth.get_open_id(access_token) # 根据openId到数据库查询是否有绑定用户 try: oauth_user = OauthUser.objects.get(openid=openId) except OauthUser.DoesNotExist: access_token = generate_save_user_token(openId) return Response({"access_token": access_token}) else: # 补充生成记录登录状态的token jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER user = oauth_user.user payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) user.token = token data = { "token": token, "user_id": user.id, "username": user.username } response = Response(data) # 合并购物车 response = merge_cart_cookie_to_redis(request, user, response) return response
def get(self, request): code = request.query_params.get("code") if not code: return Response({"message": "缺少code"}, status=status.HTTP_400_BAD_REQUEST) oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) # 通过code向qq服务器请求获取access_token try: access_token = oauth.get_access_token(code) openid = oauth.get_open_id(access_token) except Exception: logger.error("向qq服务器请求失败") return Response({'message': 'QQ服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) try: oauth_user = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 如果openid没绑定美多商城用户,创建用户并绑定到openid # 为了能够在后续的绑定用户操作中前端可以使用openid,在这里将openid签名后响应给前端 access_token_openid = generate_save_user_token(openid) return Response({'access_token': access_token_openid}) else: # 如果openid已绑定美多商城用户,直接生成JWT token,并返回 user = oauth_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) response = Response({ 'token': token, 'user_id': user.id, 'username': user.username }) return response
def get(self, request, username): username = username sms_code = request.query_params.get('sms_code') # 通过username获取手机号 user = User.objects.get(username=username) mobile = user.mobile redis_conn = get_redis_connection('verify_codes') real_sms_code = redis_conn.get('sms_%s' % mobile) # 验证短信验证码 if real_sms_code is None: return Response(status=status.HTTP_400_BAD_REQUEST) if sms_code != real_sms_code.decode(): return Response(status=status.HTTP_400_BAD_REQUEST) user_id = user.id token = generate_save_user_token(mobile) data = { "user_id": user_id, "access_token": token } return Response(data=data, status=status.HTTP_200_OK)