[d-3]django中使用JWT

1. JWT的整體流程

jwt交互流程圖.png

2. JWT的結(jié)構(gòu)組成

  • JWT是由三段信息構(gòu)成的,將這三段信息文本用.鏈接一起就構(gòu)成了Jwt字符串。就像這樣:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

  • 第一部分我們稱它為頭部(header)
  • 第二部分我們稱其為載荷(payload, 類似于飛機(jī)上承載的物品),
  • 第三部分是簽證(signature).
  • header
jwt的頭部承載兩部分信息:
聲明類型,這里是jwt
聲明加密的算法 通常直接使用 HMAC SHA256
完整的頭部就像下面這樣的JSON:

{
  'typ': 'JWT',
  'alg': 'HS256'
}
然后將頭部進(jìn)行base64加密(該加密是可以對(duì)稱解密的),構(gòu)成了第一部分.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
  • playload
載荷就是存放有效信息的地方。這個(gè)名字像是特指飛機(jī)上承載的貨品,這些有效信息包含三個(gè)部分

標(biāo)準(zhǔn)中注冊(cè)的聲明
公共的聲明
私有的聲明
標(biāo)準(zhǔn)中注冊(cè)的聲明 (建議但不強(qiáng)制使用) :

iss: jwt簽發(fā)者
sub: jwt所面向的用戶
aud: 接收jwt的一方
exp: jwt的過(guò)期時(shí)間,這個(gè)過(guò)期時(shí)間必須要大于簽發(fā)時(shí)間
nbf: 定義在什么時(shí)間之前,該jwt都是不可用的.
iat: jwt的簽發(fā)時(shí)間
jti: jwt的唯一身份標(biāo)識(shí),主要用來(lái)作為一次性token,從而回避重放攻擊。
公共的聲明 : 公共的聲明可以添加任何的信息,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息.但不建議添加敏感信息,因?yàn)樵摬糠衷诳蛻舳丝山饷?

私有的聲明 : 私有聲明是提供者和消費(fèi)者所共同定義的聲明,一般不建議存放敏感信息,因?yàn)閎ase64是對(duì)稱解密的,意味著該部分信息可以歸類為明文信息。

定義一個(gè)payload:

{
 "sub": "1234567890",
 "name": "John Doe",
 "admin": true
}
然后將其進(jìn)行base64加密,得到Jwt的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
  • signature
jwt的第三部分是一個(gè)簽證信息,這個(gè)簽證信息由三部分組成:

header (base64后的)
payload (base64后的)
secret
這個(gè)部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串,然后通過(guò)header中聲明的加密方式進(jìn)行加鹽secret組合加密,然后就構(gòu)成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
將這三部分用.連接成一個(gè)完整的字符串,構(gòu)成了最終的jwt:

  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:secret是保存在服務(wù)器端的,jwt的簽發(fā)生成也是在服務(wù)器端的,secret就是用來(lái)進(jìn)行jwt的簽發(fā)和jwt的驗(yàn)證,所以,它就是你服務(wù)端的私鑰,在任何場(chǎng)景都不應(yīng)該流露出去。一旦客戶端得知這個(gè)secret, 那就意味著客戶端是可以自我簽發(fā)jwt了。

3.如何應(yīng)用

一般是在請(qǐng)求頭里加入Authorization,并加上Bearer標(biāo)注:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

4.django-rest-framework中的應(yīng)用

  • 安裝
pip install djangorestframework-jwt
  • 配置
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # WT_EXPIRATION_DELTA 指明token的有效期
}


手動(dòng)創(chuàng)建token的方法

from rest_framework_jwt.settings import api_settings


jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)

user.token = token


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容