def check_save_user_token(cls, token, secret_key=None, expires=None): """ 对token进行校验: token: 对openid加密之后生成的token secret_key: 密钥 expires: token有效时间 """ if secret_key is None: secret_key = cls.SECRET_KEY if expires is None: expires = cls.EXPIRES_IN serializer = TJWSSerializer(secret_key, expires) try: data = serializer.loads(token) except BadData: return None else: return data.get('openid')
def get(self, request, username): # 获取找回密码的用户 # 因为我们之前重写过Django的认证后端类,所以认证方法username既可以传账号,又可以传入手机号。 user = User.objects.get(username=username) image_code = request.GET.get('text') image_code_id = request.GET.get('image_code_id') redis_image = get_redis_connection('image_codes') try: real_image_code = redis_image.get("ImageCode_" + image_code_id) # 如果图片验证码取出成功,那么删除redis中的缓存. if real_image_code: real_image_code = real_image_code.decode() redis_image.delete("ImageCode_" + image_code_id) except Exception as e: return Response({'message': '获取图片验证码失败'}, status=status.HTTP_400_BAD_REQUEST) # 判断图片验证码是否已经过期 if not real_image_code: # 过期 return Response({'message': '图片验证码已过期'}, status=status.HTTP_400_BAD_REQUEST) # 进行图片验证码的校验 if image_code.lower() != real_image_code.lower(): # 验证码输入有误 return Response({'message': '图片验证码输入有误'}, status=status.HTTP_400_BAD_REQUEST) # 将手机号加密 tjs = TJWSSerializer(settings.SECRET_KEY, 300) access_token = tjs.dumps({'user': user.mobile}).decode() # 加密手机号 per = user.mobile[0:3] back = user.mobile[-5:-1] sec = per + '****' + back # 做出响应.返回access_token和手机号 return Response({'access_token': access_token, 'mobile': sec})
def check_verify_email_token(token): """ 检查验证邮件的token """ serializer = TJWSSerializer( settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES) try: data = serializer.loads(token) # note--itsdangerous自带的错误, 如果token无效的话 except BadData: return None else: email = data.get('email') user_id = data.get('user_id') try: # tips--通过token查找用户对象 user = User.objects.get(id=user_id, email=email) except User.DoesNotExist: return None else: return user
def check_verify_email_token(token): """ 检查验证邮件的token :param token: :return: """ serializer = TJWSSerializer( settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES) try: data = serializer.loads(token) except BadData: return None else: email = data.get('email') user_id = data.get('user_id') try: user = User.objects.get(id=user_id, email=email) except User.DoesNotExist: return None else: return user
def check_email_verify_token(token): """ 检查验证邮件的token """ serializer = TJWSSerializer( settings.SECRET_KEY, expires_in=constants.EMAIL_VERIFY_TOKEN_EXPIRES) try: data = serializer.loads(token) except BadData: return None else: email = data.get('email') user_id = data.get('user_id') # try: # user = User.objects.get(id=user_id, email=email) # except User.DoesNotExist: # return None # else: # return user User.objects.filter(id=user_id, email=email).update(email_active=True) return True
def check_verify_email_token(token): """ token: 加密用户的信息 """ serializer = TJWSSerializer(secret_key=settings.SECRET_KEY) try: data = serializer.loads(token) except BadData: # 解密失败 return None else: # 解密成功 id = data['id'] email = data['email'] # 查找对应的用户 try: user = User.objects.get(id=id, email=email) except User.DoesNotExist: return None else: return user
def post(self, request, pk): """ 1.在模型类中实现检验修改密码 token 的方法,取出 data,判断 user_id 是否一样; 2.判断两次密码是否一样,判断是否是当前用户,返回数据; 3.更新密码; 4.返回重置密码成功信息。 """ user = User.objects.filter(id=pk).first() json_str = request.body json_str = json_str.decode() # python3.6 无需执行此步 req_data = json.loads(json_str) access_token = req_data.get('access_token') # 对token进行解密 sec = TJWSSerializer(settings.SECRET_KEY, 300) try: data = sec.loads(access_token) except BadData: return Response('非法请求') user_id = data.get('user_id') if user_id == int(pk): # 判断两次密码是否一致 if req_data['password'] != req_data['password2']: return Response('两次密码不一样,请仔细检查一下下...') user.set_password(req_data['password']) user.save() return Response({ 'id': user_id, 'username': user.username, 'mobile': user.mobile }) return Response('非法请求')
def get(self, request): req_code = request.query_params.get('code', None) # 获取授权码code if not req_code: return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST) try: access_token = github_token(req_code) # 向GitHub发送请求以获取access_token user_info = github_user(access_token) # 向GitHub用户API发送请求获取信息 if user_info: openid = user_info.get('id') except: return Response({'message': 'Github服务器不可用'}, status=status.HTTP_503_SERVICE_UNAVAILABLE) # 查询数据库有没有该openid try: auth_github_user = GithubUser.objects.get(openid=openid) except GithubUser.DoesNotExist: # 没有绑定openid,加密返回openid给前端暂存 备用 serializer = TJWSSerializer(settings.SECRET_KEY, 600) data = {'openid': openid} token = serializer.dumps(data) # 字节类型 openid_token = token.decode() return Response({'openid_token': openid_token}) else: user = auth_github_user.user # 生成token jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER # 引用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 return Response({ 'token': token, 'username': user.username, 'user_id': user.id })
def generate_bind_user_access_token(self, openid): serializer = TJWSSerializer( secret_key=settings.SECRET_KEY, expires_in=constants.BIND_USER_ACCESS_TOKEN_EXPIRES) token = serializer.dumps({'openid': openid}) return token.decode()
def verify_token(id, email): s = TJWSSerializer(settings.SECRET_KEY, expires_in=3600) token = s.dumps({'id': id, 'email': email}) return token.decode()
from django.test import TestCase from urllib.parse import urlencode from urllib.parse import parse_qs from urllib.request import urlopen from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer from itsdangerous import BadData # itsdangerous:进行数据的签名加密和解密 # 安装:pip install itsdangerous # Create your tests here. if __name__ == '__main__': req_data = 'eyJleHAiOjE1NDg1OTgxMTcsImlhdCI6MTU0ODU5NDUxNywiYWxnIjoiSFMyNTYifQ.eyJvcGVuaWQiOiJLREtLU0RKSkRKVVExMjgzaUtETExEIn0.F8gpRRj9P_WxPbLjruKwC-x1EuV1vDKs_m8iSuAWfbM' # 解密 serializer = TJWSSerializer(secret_key='2123456abc') try: res_dict = serializer.loads(req_data) except BadData: print("解密失败") else: # res = res_dict.get('openid',"") print(res_dict) # if __name__ == '__main__': # my_dict = { # 'openid':'KDKKSDJJDJUQ1283iKDLLD' # } # # 签名加密 # # TJWSSerializer(secret_key='秘钥',expires_in='解密有效时间:s‘) # serializer = TJWSSerializer(secret_key='123456abc',expires_in=3600)
res = urlencode(req_dict) print(res) # parse_qs:将查询字符串转换为python字典 from urllib.parse import parse_qs # 定义查询字符串 req_data1 = 'c=3&b=2&a=1&c=4' res1 = parse_qs(req_data1) # 注:当key有多个相同时,对应的value是list # itsdangerous # 数据加密 # serializer = TJWSSerializer(secret_key='加密密钥', expires_in='j解密有效时间') serializer = TJWSSerializer(secret_key='abc123', expires_in=3600) # 数据 req_dict = {'openid': '1kkdk*KDLLS*09103003'} # 加密并返回加密之后数据 res = serializer.dumps(req_dict) res = res.decode() print(res) # 数据解密 req_data = 'eyJpYXQiOjE1MzczMjU3OTAsImV4cCI6MTUzNzMyOTM5MCwiYWxnIjoiSFMyNTYifQ.eyJvcGVuaWQiOiIxa2tkaypLRExMUyowOTEwMzAwMyJ9.qsyGzXn6rHGgKbNYYxplEvgW-mPQDLlu8ArKvqNA4Wg' serializer = TJWSSerializer(secret_key='abc123') try:
def get(self, request): """ 1.前端发送请求,带上上一步生成的 access_token; 2.在模型类中定义验证 token 的方法,使用 itdangerous 提供的方法进行反验证,取出存在token 中的手机号,进行判断是否在 60s 内,防止重复发送; 3.生成短信验证码,存入 redis,使用异步 celery 发送短信; 4.返回成功消息; """ # 获取上一步的access_token access_token = request.GET.get('access_token') # 对获取到的token进行解密校验.并且获取手机号 serializer = TJWSSerializer(settings.SECRET_KEY, 300) try: data = serializer.loads(access_token) except BadData: return None mobile = data.get('user') if mobile: # 判断给<mobile>60s内是否发送过短信 redis_conn = get_redis_connection('verify_codes') send_flag = redis_conn.get('send_flag_%s' % mobile) # None if send_flag: # 60秒内给<mobile>发送过短信了 return Response({'message': '您点击过于频繁了,休息一会吧...'}, status=status.HTTP_403_FORBIDDEN) # 1.随机生成6位的数字作为短信验证码 sms_code = '%06d' % random.randint(0, 999999) logger.info("短信验证码是 = %s" % sms_code) # 2.在redis中存储短信验证码内容,以'sms_<mobile>'为key,以验证码的内容为value # redis_conn = get_redis_connection('verify_codes') # redis_conn.set('<key>','<value>','<expires>') # redis_conn.setex('<key>','<expires>','<value>') # redis_conn.setex('sms_%s' % mobile,constants.SMS_CODE_REDIS_EXPIRES, sms_code) # redis_conn.setex('send_flag_%s' % mobile,constants.SEND_SMS_CODE_INTERVAL,1) # 创建redis管道对象 pl = redis_conn.pipeline() # 向redis管道中添加命令 pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) # 一次性执行管道中的所有命令 pl.execute() # 3.使用云通讯给mobile发送短信 # 创建一个进程调用发送短信的函数 from celery_tasks.sms.tasks import send_sms_code send_sms_code.delay(mobile, sms_code) # 4.返回应答,短信发送成功 return Response({'message': 'OK'}) return Response({'message': '发送失败'})
def generate_bind_user_access_token(self, openid): # 先创建对象 serializer = Serializer(秘钥, 有效期秒) serializer = TJWSSerializer(settings.SECRET_KEY, constants.BIND_USER_ACCESS_TOKEN_EXPIRES) token = serializer.dumps({'openid': openid}) #返回bytes类型 return token.decode() #转成字符串类型
def dumps(data_dict, expires): serializer = TJWSSerializer(settings.SECRET_KEY, expires) return serializer.dumps(data_dict).decode()
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer from itsdangerous import BadData # TJWSSerializer(secret_key='加解密密钥', expires_in='解密有效时间') # 假如密钥: 123abc # data = { # 'openid': 'AKKDKdk818289kKDOIkdka01929390' # } # serializer = TJWSSerializer(secret_key='123abc', expires_in=3600) # # res = serializer.dumps(data) # bytes # res = res.decode() # print(res) # 解密 data = 'eyJhbGciOiJIUzI1NiIsImV4cCI6MTUzNTI1MzEyMCwiaWF0IjoxNTM1MjQ5NTIwfQ.eyJvcGVuaWQiOiJBS0tES2RrODE4Mjg5a0tET0lrZGthMDE5MjkzOTAifQ.DeFTW0zwnDwU7jSCL8QCTQInpz01TGNb6cZHZHu502I' serializer = TJWSSerializer(secret_key='123abc', expires_in=3600) try: res = serializer.loads(data) except BadData as e: print(e) else: print(res) # if __name__ == "__main__": # # 将python字典转化成一个查询字符串 # # data = { # # 'id': 1, # # 'username': '******' # # } # #
def make_token(secret_key, data, expires): s = TJWSSerializer(secret_key, expires_in=expires) token = s.dumps(data) return token