1. 程式人生 > >Tornado集成JSON Web Token方式登錄

Tornado集成JSON Web Token方式登錄

tex field 組織 api sta 前端測試 nag tor settings

本項目github地址
前端測試模板如下:
技術分享圖片

Tornado restful api 項目

項目結構如下:
技術分享圖片
項目組織類似於django,由獨立的app模塊構成。

登錄接口設計

模式:post -> /login/
攜帶參數:{username:"", password:""}
返回:{token: "這裏是JWT"}
技術分享圖片

Tornado集成JWT

Pyjwt的github地址
首先安裝Pyjwt第三方庫

$ pip install pyjwt

配置Pyjwt

jwt_expire 單位為秒,圖中的表明token7天過期
技術分享圖片

接口編寫如下

import jwt
class LoginHandler(BaseHandler):
    '''
    用戶登錄
    post -> /login/
    payload:
        {
            "username": "用戶名或者郵箱",
            "password": "密碼"
        }
    '''
    async def post(self, *args, **kwargs):
        res = {}

        data = self.request.body.decode("utf-8")
        data = json.loads(data)
        form = LoginForm.from_json(data)
        if form.validate():
            username = form.username.data
            password = form.password.data
            try:
                query = UserProfile.select().where(
                    (UserProfile.username==username) | (UserProfile.email==username)
                )
                user = await self.application.objects.execute(query)
                try:
                    user = user[0]
                except IndexError as e:
                    self.set_status(400)
                    res['non_fields'] = '不存在該用戶'
                    self.finish(res)
                    return
                if not user.password.check_password(password):
                    res['non_fields'] = '用戶名或密碼錯誤'
                    self.set_status(400)
                else:
                    payload = {
                        'id': user.id,
                        'username': username,
                        'exp': datetime.utcnow()
                    }
                    token = jwt.encode(payload, self.settings["secret_key"], algorithm='HS256')
                    res['token'] = token.decode('utf-8')
                    res['username'] = username
            except UserProfile.DoesNotExist:
                self.set_status(400)
                res['username'] = '用戶不存在'

        else:
            self.set_status(400)
            for field in form.errors:
                res[field] = form.errors[field]

        self.finish(res)

關鍵是這裏:

payload = {
    'id': user.id,
    'username': username,
    'exp': datetime.utcnow()
}
token = jwt.encode(payload, self.settings["secret_key"], algorithm='HS256')
res['token'] = token.decode('utf-8')
res['username'] = username

用HS256加密算法和自己的私鑰來加密payload轉換成token並返回。

測試接口:

技術分享圖片

成功返回數據!以後再訪問需要登錄的頁面時,在請求頭(request header)中加入這個字段就可以了!
技術分享圖片

Tornado集成JSON Web Token方式登錄