锲子
最近开始转战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。