返回顶部

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')
View Code

 

定义服务器检查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
        }
View Code

 

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
View Code

 

 

用户在访问其他的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')
View Code

Authorization:即在登录的时候返回的token 

 

posted @ 2018-04-12 11:27  Crazymagic  阅读(378)  评论(0编辑  收藏  举报