JWT Authorization in Python aiohttp

锲子

最近开始转战Python后台,正在开始使用异步的aiohttp。由于是新的框架,参考资料少之又少。尤其是习惯了用ORM模型,但是aiohttp不支持,无奈只能慢慢来。

好了进入正题,十一回来开始搞authorization token(刚开始一个新的项目),之前有用过itsdangerous,然后wenzhi大神推荐了JWT,接下来记录一下在aiohttp中使用JWT。

1、安装

pip install -r requirements.txt
2、LOGIN

from datetime import datetime, timedelta
import jwt

JWT_SECRET = 'secret'
JWT_ALGORITHM = 'HS256'
JWT_EXP_DELTA_SECONDS = 20

async def login(request):
    post_data = await request.post()

    try:
        user = User.objects.get(email=post_data['email'])
        user.match_password(post_data['password'])
    except (User.DoesNotExist, User.PasswordDoesNotMatch):
        return json_response({'message': 'Wrong credentials'}, status=400)

    payload = {
        'user_id': user.id,
        'exp': datetime.utcnow() + timedelta(seconds=JWT_EXP_DELTA_SECONDS)
    }
    jwt_token = jwt.encode(payload, JWT_SECRET, JWT_ALGORITHM)
    return json_response({'token': jwt_token.decode('utf-8')})

app = web.Application()
app.router.add_route('POST', '/login', login)
(1)获取post的data

(2)通过email获取user object

(3)验证密码

(4)验证user信息出错抛异常

(5)创建token payload, 其中user_id为token主信息,exp为token时效

(6)通过JWT encode token 返回

3、Auth Middleware

async def get_user(request):
    return json_response({'user': str(request.user)})

async def auth_middleware(app, handler):
    async def middleware(request):
        request.user = None
        jwt_token = request.headers.get('authorization', None)
        if jwt_token:
            try:
                payload = jwt.decode(jwt_token, JWT_SECRET,
                                     algorithms=[JWT_ALGORITHM])
            except (jwt.DecodeError, jwt.ExpiredSignatureError):
                return json_response({'message': 'Token is invalid'}, status=400)

            request.user = User.objects.get(id=payload['user_id'])
        return await handler(request)
    return middleware

app = web.Application(middlewares=[auth_middleware])
加入middleware后,每次route handler 都会检查request中的authorization,有的话,将token decode 出之前的payload信息,存入request中,供handler使用。

4、解释器login_required

def login_required(func):
    def wrapper(request):
        if not request.user:
            return json_response({'message': 'Auth required'}, status=401)
        return func(request)
    return wrapper
这样就可以在handler函数之前加入@login_required解释器,从而实现authorization token。

5、总结

通过生成payload token,可以存储一些用户信息,不局限于id。通过middleware decode authorization获取这些信息,从而方便的进行authorization token。


你可能感兴趣的:(Python)