jwt权限认证
项目的目录如下所示:
在用户登录的时候生成token值
在App/login.py代码如下所示
import jwt import datetime from sanic.views import HTTPMethodView from sanic.response import json from sanic import Blueprint from Model.DB import * from Lib import ErrorCode as EC from Auth import Jwt_config as JWTConfig LoginBlueprint = Blueprint(__name__, url_prefix='/api/v1/') class AuthHandler(HTTPMethodView): def __init__(self): self.Optional_parameters = {} self.Required_Field = ['Class_Room_Uid', 'Class_Room_Password'] def _set_token(self): self.encodeds = jwt.encode({ 'relate_info': { "Class_Room_Uid": self.Class_Room_Uid, "Rucode": self.Rucode }, 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=JWTConfig.EXP)}, JWTConfig.SECRET_KEY, algorithm=JWTConfig.ALGORITHM ) async def _get_db_class_room_resource(self): # 查找当前认证班级 currentClassRoom = await SS_ClassRoom.find_one({ "Class_Room_Uid": self.Class_Room_Uid }) if currentClassRoom: if currentClassRoom.Class_Room_Password == self.Class_Room_Password: # 密码通过验证 self.Rucode = currentClassRoom['Rucode'] self._set_token() self.code = 200 result = { "token": self.encodeds, "Class_Room_oid": str(currentClassRoom["_id"]) } else: # 未通过验证 self.code = 7102 result = "用户名或者密码错误!" else: self.code = 7102 result = "用户名或者密码错误" return result async def post(self, request): self.Class_Room_Uid = request.json.get("Class_Room_Uid","").strip() self.Class_Room_Password = request.json.get("Class_Room_Password","").strip() if self.Class_Room_Uid and self.Class_Room_Password: res = await self._get_db_class_room_resource() result = await EC.ResponseReturn(code=self.code, data=res) else: result = await EC.ResponseReturn(code=702, data="") return json(result) LoginBlueprint.add_route(AuthHandler.as_view(), 'login')
定义服务器检查token的封装函数
Auth/jwt_config.py的代码如下:
SECRET_KEY = "www.baidu.com" ALGORITHM = 'HS256' EXP = 2 LEEWAY = 1800 OPTIONS = { 'verify_signature': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iat': True, 'verify_aud': False }
Auth/__init__.py的代码如下:
# -*- coding:utf-8 -*- import jwt from Lib import ErrorCode as EC from sanic.response import json import time import datetime from . import Jwt_config as JWTConfig import json as js from jwt import ( InvalidTokenError, DecodeError, InvalidAudienceError, ExpiredSignatureError, ImmatureSignatureError, InvalidIssuedAtError, InvalidIssuerError, ExpiredSignature, InvalidAudience, InvalidIssuer, MissingRequiredClaimError ) def jwtauth(origin_func): async def wrapper(self,request, *args, **kwargs): try: # 在token 中封装了 "Authorization":"token的值存在这个字典里面" auth = request.token if auth: parts = auth.split() # 如果有多个值的话就是失效的token if len(parts) > 1: result = await EC.ResponseReturn(code=7407, data="无效Token") return json(result) token = auth try: res = jwt.decode( token, JWTConfig.SECRET_KEY, leeway=JWTConfig.LEEWAY, options=JWTConfig.OPTIONS ) self.cache = res except (InvalidTokenError, DecodeError, InvalidAudienceError, ExpiredSignatureError, ImmatureSignatureError, InvalidIssuedAtError, InvalidIssuerError, ExpiredSignature, InvalidAudience, InvalidIssuer, MissingRequiredClaimError) as e: result = await EC.ResponseReturn(code=7403, data=str(e)) return json(result) response = await origin_func(self,request, *args, **kwargs) # print(res['exp'] - int(time.mktime(datetime.datetime.now().timetuple()))) 当过时间小于现在的时间戳就重新设置token值 if res['exp'] < int(time.mktime(datetime.datetime.now().timetuple())): print(res) newtoken = jwt.encode({ 'relate_info': res['relate_info'], 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=JWTConfig.EXP)}, JWTConfig.SECRET_KEY, algorithm=JWTConfig.ALGORITHM) body = js.loads(response.body) body['token'] = newtoken.decode('utf-8') response.body = js.dumps(body).encode('utf-8') return response else: result = await EC.ResponseReturn(code=7406, data="Tokenmissimg") return json(result) except Exception as ec: result = await EC.ResponseReturn(code=705, data=str(ec)) return json(result) return wrapper
用户在访问其他的url视图函数的时候只需要加上检查的封装函数即可
在index.py中定义一个路由
from sanic.views import HTTPMethodView from sanic.response import json from sanic import Blueprint from Auth import jwtauth ListingBlueprint = Blueprint(__name__, url_prefix='/api/v1/') class Index(CustomHTTPMethodView): @jwtauth async def get(self, request): return json({"return": 1}) ListingBlueprint.add_route(Index.as_view(), 'index')
Authorization:即在登录的时候返回的token