JWT認證機制

1. 定義

Json web token (JWT), 是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519).該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登陸(SSO)場景。JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。html

2. 傳統的Session認證

2.1 流程

session認證的流程通常以下:python

  1. 用戶向服務器發送用戶名和密碼。web

  2. 服務器驗證經過後,在當前對話(session)裏面保存相關數據,好比用戶角色、登陸時間等等。算法

  3. 服務器向用戶返回一個 session_id,寫入用戶的 Cookie。django

  4. 用戶隨後的每一次請求,都會經過 Cookie,將 session_id 傳回服務器。瀏覽器

  5. 服務器收到 session_id,找到前期保存的數據,由此得知用戶的身份。安全

2.2 缺點

  • session保存在服務器,當註冊用戶不少,會增長服務器的開銷。bash

  • 用戶認證以後,服務端作認證記錄,若是認證的記錄被保存在內存中的話,這意味着用戶下次請求還必需要請求在這臺服務器上,這樣才能拿到受權的資源,這樣在分佈式的應用上,限制了負載均衡的能力。這也意味着限制了應用的擴展能力。服務器

  • session是基於cookie來進行用戶識別的, cookie若是被截獲,用戶就會很容易受到跨站請求僞造(CSRF)的攻擊。cookie

3.JWT認證

3.1 token

JWT是基於token的鑑權機制相似於http協議也是無狀態的,它不須要在服務端去保留用戶的認證信息或者會話信息。這就意味着基於token認證機制的應用不須要去考慮用戶在哪一臺服務器登陸了,這就爲應用的擴展提供了便利。

3.2 流程

  1. 用戶使用用戶名密碼來請求服務器

  2. 服務器進行驗證用戶的信息

  3. 服務器經過驗證發送給用戶一個token

  4. 客戶端存儲token,並在每次請求時附送上這個token值

  5. 服務端驗證token值,並返回數據

這個token必需要在每次請求時傳遞給服務端,它應該保存在請求頭裏, 另外,服務端要支持CORS(跨來源資源共享)策略,通常咱們在服務端這麼作就能夠了Access-Control-Allow-Origin: *

3.3 JWT構成

第一部分咱們稱它爲頭部(header),第二部分咱們稱其爲載荷(payload),第三部分是簽證(signature).

官方連接jwt.io/

header

jwt的頭部承載兩部分信息:

  • 聲明類型,這裏是jwt

  • 聲明加密的算法 一般直接使用 SHA256

# 頭部相似以下信息:{ "alg": "HS256", "typ": "JWT"}複製代碼

將頭部進行base64加密(該加密是能夠對稱解密的),構成了第一部分.獲得的加密信息是以下的一串字符串:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9複製代碼
payload

載荷就是存放有效信息的地方。這些有效信息包含三個部分:

  • 標準中註冊的聲明

  • 公共的聲明

  • 私有的聲明

{  "name": "John",  "admin": true,  「email」:"xxx@gmail.com"}複製代碼

該部分也是base64加密的,加密後獲得下面字符串:

ewogICJuYW1lIjogIkpvaG4iLAogICJhZG1pbiI6IHRydWXvvIwKICDigJxlbWFpbOKAnToieHh4QGdtYWlsLmNvbSIKfQ複製代碼
signature

JWT的第三部分是一個簽證信息,這個簽證信息由三部分組成:

  • header (base64加密)

  • payload (base64加密)

  • secret 密鑰

這個部分須要base64加密後的headerbase64加密後的payload使用.鏈接組成的字符串,而後經過header中聲明的加密方式進行SHA256組合加密(不可逆加密),而後就構成了jwt的第三部分。將這三部分用.鏈接成一個完整的字符串,構成了最終的jwt

注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,因此,它就是你服務端的私鑰,在任何場景都不該該流露出去。一旦客戶端得知這個secret, 那就意味着客戶端是能夠自我簽發jwt了。若是以爲密鑰泄露了,請及時修改。

4. 後臺設置

下面介紹的是在djangorestframework基礎上的jwt集成方案。首先確保djangorestframework在設置文件中應用中註冊。

安裝

pip install djangorestframework-jwt複製代碼

配置

INSTALLED_APPS = [
    ...
    'djangorestframework',
    ...
]
# 認證
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), # JWT_EXPIRATION_DELTA 指明token的有效期
}複製代碼

路由

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    # JWT 完成登陸
    url(r'^authorizations/$', obtain_jwt_token),
]複製代碼

利用djangorestframework-jwt生成的token值保存在瀏覽器的Storage中。

相關文章
相關標籤/搜索