用戶身份認證一般有5種方式
-
HTTP Basic authentication
在發送請求時在HTTP頭中加入authentication
字段,將用Base64
編碼的用戶名和密碼作爲值,每次發送請求的時候都要發送用戶名和密碼,實現比較簡單。 -
Cookies
向後臺發送用戶名和密碼,在用戶名和密碼通過驗證後,保存返回的Cookie
作爲用戶已經登錄的憑證,每次請求時附帶這個Cookie
-
Signatures
用戶拿到服務器給的私鑰,在發送請求前,將整個請求使用私鑰來加密,發送的將是一串加密信息,此方式只適用於API -
One-Time Passwords
一次一密,每次登錄時使用不同的密碼,一般由服務端通過郵件將密碼發給用戶,這種登錄方式比較繁瑣 -
JSON Web Token
用戶發送按照約定,向服務端發送Header
、Payload
和Signature
,幷包含認證信息(密碼),驗證通過後服務端返回一個token
,之後用戶使用該token
作爲登錄憑證,適合於移動端和api
因爲前後端分離的緣故,現在的後臺多數只提供數據部分,一般使用JSON
格式,所以JSON
Web Token
是比較流行的認證方式。
JWT
的認證方式相比其他的認證方式有一下優點:
- 信息可用HMAC或RSA加密,信息安全性較高
- 生成的密文短,密文可以包含所有用戶信息,認證過期時間或用戶權限等自定義信息
- 適合用於手機應用和單頁面應用的身份認證
-
使用靈活,一旦取得了
JWT
,可以通過POST方式或添加入HTTP頭中發送
JWT結構
JWT
包含3個部分
- Header (頭部)
- Payload (負載)
- Signature (簽名)
Header
1 2 3 4 |
{ "alg": "HS256", "typ": "JWT" } |
JWT
的頭部是固定的,alg
是算法的意思表示該JWT
使用的是何種算法加密。typ
字段值是固定的JWT
Payload
1 2 3 4 5 |
{ "sub": "1234567890", "name": "John Doe", "admin": true } |
負載部分就是具體的認證信息,通過修改這部分的內容來控制認證信息如用戶權限等。除了一些保留字段exp
(過期時間)、aud
、iss
等外,使用方法跟普通Json一樣。
Signature
簽名,也就是密鑰,用來保證密文的安全強度
以上3部分都經過Base64Url處理後用下載地址 .
分隔再使用HMAC
SHA256
或RSA
加密爲一段字符串
1 2 3 4 |
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) |
JWT使用流程
客戶端POST用戶名和密碼到服務端,若對安全要求較高可以是加密後的用戶名或密碼,服務端把拿到的用戶名和密碼與數據庫中的對比,若相同則按照上面的流程生成JWT
,然後返回客戶端。在此之後客戶端的所有請求,可以在Authorization
HTTP頭或POST數據中附帶得到的JWT
。服務端驗證JWT
並解析出Payload下載地址 部分,以此來判斷用戶的權限。
JWT
的使用方法很簡單,就拿node.js的包node-jsonwebtoken
來說加密和驗證就兩個函數jwt.sign
,jwt.verify
並且jwt.io中提供了很多語言的JWT
包。