基於session的認證
jwt認證規則
jwt: json web token
# 優點:
1)數據庫不需要存儲token,所以服務器的 IO 操作會減少(沒有IO寫操作)
2)客戶端存Token,服務器只存儲簽發與校驗算法,執行效率高
3)簽發與校驗算法在多個服務器上可以直接統一,所以jwt認證規則下,服務器做集群非常便捷
# 突破點:
1)token必須要有多個部分組成,有能反解的部分,也要有不能反解的部分 - jwt采用的都是三段式
2)token中必須包含過期時間,保證token的安全性與時效性
# jwt原理:
1)jwt由 頭.載荷.簽名 三部分組成
2)每一部分數據都是一個json字典,頭和載荷采用 base64 可逆加密算法加密,簽名采用 HS256 不可逆加密
內容:
1)頭(基本信息):可逆不可逆采用的加密算法、公司名稱、項目組信息、開發者信息...
{
"company": "小女孩",
...
}
2)載荷(核心信息):用戶主鍵、用戶賬號、客戶端設備信息、過期時間...
{
'pk': 1,
...
}
3)簽名(安全信息):頭的加密結果、載荷的加密結果、服務器的安全碼(鹽)...
{
"header": "..."
...
}
# 簽發算法:
1)頭內容寫死(可以為空{}):公司、項目組信息都是固定不變的
=> 將數據字典轉化成json字符串,再將json字符串加密成base64字符串
2)載荷的內容:用戶賬號、客戶端設備信息是由客戶端提供,用戶主鍵是客戶端提供賬號密碼校驗User表通過后才能確定,過期時間根據當前時間與配置的過期時間相結合產生
=> 將數據字典轉化成json字符串,再將json字符串加密成base64字符串
3)簽名的內容,先將頭的加密結果,載荷的加密結果作為成員,再從服務器上拿安全碼(不能讓任何客戶端知道),也可以額外包含載荷的部分(用戶信息,設備信息)
=> 將數據字典轉化成json字符串,再將json字符串不可逆加密成HS256字符串
4)將三個字符串用 . 連接產生三段式token
# 校驗算法:
1)從客戶端提交的請求中拿到token,用 . 分割成三段(如果不是三段,非法)
2)頭(第一段)可以不用解密
3)載荷(第二段)一定需要解密,先base64解密成json字符串,再轉換成json字典數據
i)用戶主鍵與用戶賬號查詢User表確定用戶是否存在
ii)設備信息用本次請求提交的設備信息比對,確定前后是否是同一設備,決定是否對用戶做安全提示(eg:短信郵箱提示異地登錄)(同樣的安全保障還可以為IP、登錄地點等)
iii)過期時間與當前時間比對,該token是否在有效時間內
4)簽名(第三段)采用加密碰撞校驗
i)將頭、載荷加密字符串和數據庫安全碼形成json字典,轉換成json字符串
ii)采用不可逆HS256加密形成加密字符串
iii)新的加密字符串與第三段簽名碰撞比對,一致才能確保token是合法的
5)前方算法都通過后,載荷校驗得到的User對象,就是該token代表的登錄用戶(Django項目一般都會把登錄用戶存放在request.user中)
# 刷新算法:
1)要在簽發token的載荷中,額外添加兩個時間信息:第一次簽發token的時間,最多往后刷新的有效時間
2)每一請求攜帶token,不僅走校驗算法驗證token是否合法,還要額外請求刷新token的接口,完成token的刷新:校驗規則與校驗算法差不多,但是要將過期時間后移(沒有超過有效時間,產生新token給客戶端,如果超過了,刷新失敗)
3)所以服務器不僅要配置過期時間,還需要配置最長刷新時間