鑒權(quán)和身份認(rèn)證
? 所謂鑒權(quán)就是身份認(rèn)證,就是驗證您是否有權(quán)限從服務(wù)器訪問或操作相關(guān)數(shù)據(jù)。通俗的講就是一個門禁,您想要進入室內(nèi),必須通過門禁驗證身份,這就是鑒權(quán),如打開一個網(wǎng)站必須要輸入用戶名和密碼才可以登錄進入,這種就是鑒權(quán),還有一些業(yè)務(wù)需要登錄以后才可以進行,因為需要token值,則就可以把token添加到鑒權(quán)中,這種也是鑒權(quán)。
常用的鑒權(quán)方式
- Basic 認(rèn)證:戶籍部門已給你簽發(fā)了一張身份證。你每次去辦事,都要帶上身份證證,后臺要拿你的身份證去系統(tǒng)上查一下。
- Session 認(rèn)證:戶籍部門已給你簽發(fā)了一張身份證,但只告訴你身份證號碼。你每次去辦事,只要報出你的身份證號碼,后臺要查一個即否有效。
- Token 認(rèn)證:戶籍部門已給你簽發(fā)了一張有防偽功能的身份證。你每次去辦事,只要出示這張卡片,它就知道你一定是自己人。
1、Basic
HTTP Basic Authentication
在這種認(rèn)證方法下,用戶每次發(fā)送請求時,請求頭中都必須攜帶能通過認(rèn)證的身份信息。
其交互過程如下:
-
開始時,客戶端發(fā)送未攜帶身份信息的請求。
-
服務(wù)端返回 401 Unauthorized 狀態(tài),并在返回頭中說明要用
Basic
方法進行認(rèn)證:WWW-Authenticate: Basic
。 -
客戶端重新發(fā)送請求,并將身份信息包含在請求頭中:
Authorization: Basic aHk6bXlwYXNzd29yZA==
。 -
服務(wù)端驗證請求頭中的身份信息,并相應(yīng)返回 200 OK 或 403 Forbidden 狀態(tài)。
-
之后,客戶端每次發(fā)送請求都在請求頭中攜帶該身份信息
其中傳送的身份信息是 <username>:<password>
經(jīng) base64 編碼后的字串。如本例中的 aHk6bXlwYXNzd29yZA==
, 經(jīng) base64 解碼后為 hy:mypassword
。
這種認(rèn)證方法的優(yōu)點是簡單,容易理解。
缺點有:
- 不安全:認(rèn)證身份信息用明文傳送,因此需結(jié)合 https 使用。
- 效率低:服務(wù)端處理請求時,每次都需要驗證身份信息,如用戶名和密碼。
2、session
這種認(rèn)證方法結(jié)合了 Session 和 Cookie。服務(wù)端將本次會話信息以 Session 對象的形式保存在服務(wù)端的內(nèi)存、數(shù)據(jù)庫或文件系統(tǒng)中,并將對應(yīng)的 Session 對象 ID 值 SessionID 以 Cookie 形式返回給客戶端,SessionID 保存在客戶端的 Cookie 中。
這是一種有狀態(tài)的認(rèn)證方法:服務(wù)端保存 Session 對象,客戶端以 Cookie 形式保存 SessionID。
其交互過程如下:
- 客戶端在登錄頁面輸入身份信息,如用戶名/密碼。
- 服務(wù)端驗證身份信息,通過后生成一個 Session 對象,保存到服務(wù)端,并將 SessionID 值以 Cookie 形式返回給客戶端。
- 客戶端將接收到的 SessionID 保存到 Cookie 中,并且之后每次請求都在請求頭中攜帶 SessionID Cookie。
- 服務(wù)端從請求的 Cookie 中獲取 SessionID,并查詢其對應(yīng)的 Session 對象,從而獲得身份信息。
- 客戶端退出本次會話后,客戶端刪除 SessionID 的 Cookie,服務(wù)端刪除 Session 對象。
- 如果客戶端之后要重新登錄,需重新生成 Session 對象和 SessionID。
優(yōu)點:
- 較安全:客戶端每次請求時無需發(fā)送身份信息,只需發(fā)送 SessionID。
- 較高效:服務(wù)端無需每次處理請求時都要驗證身份信息,只需通過 SessionID 查詢 Session 對象。
缺點:
- 擴展性差,Session 對象保存在服務(wù)端,如果是保存在多個服務(wù)器上,有一致性問題,如果保存在單個服務(wù)器上,無法適應(yīng)用戶增長。
- 基于 Cookie 的 SessionID 不能跨域共享,同一用戶的多個客戶端(如瀏覽器客戶端和 APP)不能共享 SessionId。
- 基于 Cookie 的 SessionID 易被截獲生成 CSRF 攻擊。
3、Token
Token驗證(包括JWT,SSO)
這是一種 SPA 應(yīng)用(單頁Web應(yīng)用single page web application
)和 APP 經(jīng)常使用的認(rèn)證方法。它是一種無狀態(tài)的認(rèn)證方法。
客戶端首先將用戶信息發(fā)送給服務(wù)端,服務(wù)端根據(jù)用戶信息+私鑰生成一個唯一的 Token 并返回給客戶端。Token 只保存在客戶端,之后客戶端的每個請求頭中都攜帶 Token,而服務(wù)端只通過運算(無需查詢)來驗證用戶。
- 客戶端使用用戶名和密碼請求登錄
- 服務(wù)端收到請求,驗證用戶名和密碼
- 驗證成功后,服務(wù)端會簽發(fā)一個token,再把這個token返回給客戶端
- 客戶端收到token后可以把它存儲起來,比如放到cookie中
- 客戶端每次向服務(wù)端請求資源時需要攜帶服務(wù)端簽發(fā)的token,可以在cookie或者h(yuǎn)eader中攜帶
- 服務(wù)端收到請求,然后去驗證客戶端請求里面帶著的token,如果驗證成功,就向客戶端返回請求數(shù)據(jù)
優(yōu)點:
- Token 只保存在客戶端,因此不影響服務(wù)端擴展性。
- 為用戶生成的 Token 可以在多個客戶端共用。
- 支持跨域訪問:cookie是無法跨域的,而token由于沒有用到cookie(前提是將token放到請求頭中),所以跨域后不會存在信息丟失問題
- 無狀態(tài):token機制在服務(wù)端不需要存儲session信息,因為token自身包含了所有登錄用戶的信息,所以可以減輕服務(wù)端壓力
- 更適用CDN:可以通過內(nèi)容分發(fā)網(wǎng)絡(luò)請求服務(wù)端的所有資料
- 更適用于移動端:當(dāng)客戶端是非瀏覽器平臺時,cookie是不被支持的,此時采用token認(rèn)證方式會簡單很多
- 無需考慮CSRF:由于不再依賴cookie,所以采用token認(rèn)證方式不會發(fā)生CSRF,所以也就無需考慮CSRF的防御
缺點:
- Token 包含了用戶的全部信息,不只是如 SessionID 類似的一個 ID 值,因此會增加每次請求包的大小。
目前使用較多的是基于JWT(JSON Web Tokens) 的 Token 認(rèn)證法。
JWT
token認(rèn)證的一種實現(xiàn)方式。特別適用于分布式站點的單點登錄(SSO)場景,是目前最流行的跨域認(rèn)證解決方案。
https://jwt.io/
? 通俗地說,JWT的本質(zhì)就是一個字符串,它是將用戶信息保存到一個Json字符串中,然后進行編碼后得到一個JWT token
,并且這個JWT token
帶有簽名信息,接收后可以校驗是否被篡改,所以可以用于在各方之間安全地將信息作為Json對象傳輸。
JWT的認(rèn)證流程
- 首先,前端通過Web表單將自己的用戶名和密碼發(fā)送到后端的接口,這個過程一般是一個
POST
請求。建議的方式是通過SSL加密的傳輸(HTTPS),從而避免敏感信息被嗅探。 - 后端核對用戶名和密碼成功后,將包含用戶信息的數(shù)據(jù)作為JWT的Payload,將其與JWT Header分別進行Base64編碼拼接后簽名,形成一個JWT Token,形成的JWT Token就是一個如同lll.zzz.xxx的字符串
- 后端將JWT Token字符串作為登錄成功的結(jié)果返回給前端。前端可以將返回的結(jié)果保存在瀏覽器中,退出登錄時刪除保存的JWT Token即可
- 前端在每次請求時將JWT Token放入HTTP請求頭中的Authorization屬性中(解決XSS和XSRF問題)
- 后端檢查前端傳過來的JWT Token,驗證其有效性,比如檢查簽名是否正確、是否過期、token的接收方是否是自己等等
- 驗證通過后,后端解析出JWT Token中包含的用戶信息,進行其他邏輯操作(一般是根據(jù)用戶信息得到權(quán)限等),返回結(jié)果
JWT結(jié)構(gòu)
? JWT由3部分組成:標(biāo)頭(Header)、有效載荷(Payload)和簽名(Signature)。在傳輸?shù)臅r候,會將JWT的3部分分別進行Base64編碼后用.
進行連接形成最終傳輸?shù)淖址?/p>
JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
1.Header
? JWT頭是一個描述JWT元數(shù)據(jù)的JSON對象,alg屬性表示簽名使用的算法,默認(rèn)為HMAC SHA256(寫為HS256);typ屬性表示令牌的類型,JWT令牌統(tǒng)一寫為JWT。最后,使用Base64 URL算法將上述JSON對象轉(zhuǎn)換為字符串保存
{
"alg": "HS256",
"typ": "JWT"
}
2.Payload
? 有效載荷部分,是JWT的主體內(nèi)容部分,也是一個JSON對象,包含需要傳遞的數(shù)據(jù)。 JWT指定七個默認(rèn)字段供選擇
- iss (issuer):簽發(fā)人
- exp (expiration time):過期時間
- sub (subject):主題
- aud (audience):受眾
- nbf (Not Before):生效時間
- iat (Issued At):簽發(fā)時間
- jti (JWT ID):編號
? 這些預(yù)定義的字段并不要求強制使用。除以上默認(rèn)字段外,我們還可以自定義私有字段,一般會把包含用戶信息的數(shù)據(jù)放到payload中,如下例:
{
"sub": "1234567890",
"name": "Helen",
"admin": true
}
? 請注意!默認(rèn)情況下JWT是未加密的,因為只是采用base64算法,拿到JWT字符串后可以轉(zhuǎn)換回原本的JSON數(shù)據(jù),任何人都可以解讀其內(nèi)容,因此不要構(gòu)建隱私信息字段,比如用戶的密碼一定不能保存到JWT中,以防止信息泄露。JWT只是適合在網(wǎng)絡(luò)中傳輸一些非敏感的信息。
3.Signature
? 簽名哈希部分是對上面兩部分?jǐn)?shù)據(jù)簽名,需要使用base64編碼后的header和payload數(shù)據(jù),通過指定的算法生成哈希,以確保數(shù)據(jù)不會被篡改。首先,需要指定一個密鑰(secret)。該密碼僅僅保存在服務(wù)器中,并且不能向用戶公開。然后,使用header中指定的簽名算法(默認(rèn)情況下為HMAC SHA256)根據(jù)以下公式生成簽名。
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
在計算出簽名哈希后,JWT頭,有效載荷和簽名哈希的三個部分組合成一個字符串,每個部分用.
分隔,就構(gòu)成整個JWT對象
注意JWT每部分的作用,在服務(wù)端接收到客戶端發(fā)送過來的JWT token之后:
- header和payload可以直接利用base64解碼出原文,從header中獲取哈希簽名的算法,從payload中獲取有效數(shù)據(jù)
- signature由于使用了不可逆的加密算法,無法解碼出原文,它的作用是校驗token有沒有被篡改。服務(wù)端獲取header中的加密算法之后,利用該算法加上secretKey對header、payload進行加密,比對加密后的數(shù)據(jù)和客戶端發(fā)送過來的是否一致。注意secretKey只能保存在服務(wù)端,而且對于不同的加密算法其含義有所不同,一般對于MD5類型的摘要加密算法,secretKey實際上代表的是鹽值
增加JWT的安全性
- 因為JWT是在請求頭中傳遞的,所以為了避免網(wǎng)絡(luò)劫持,推薦使用HTTPS來傳輸,更加安全
- JWT的哈希簽名的密鑰是存放在服務(wù)端的,所以只要服務(wù)器不被攻破,理論上JWT是安全的。因此要保證服務(wù)器的安全
- JWT可以使用暴力窮舉來破解,所以為了應(yīng)對這種破解方式,可以定期更換服務(wù)端的哈希簽名密鑰(相當(dāng)于鹽值)。這樣可以保證等破解結(jié)果出來了,你的密鑰也已經(jīng)換了
4、OAuth(開放授權(quán))
? OAuth是Open Authority的縮寫。OAuth 就是一種授權(quán)機制。用來授權(quán)第三方應(yīng)用,獲取用戶數(shù)據(jù)。通過數(shù)據(jù)的所有者授權(quán)第三方應(yīng)用進入系統(tǒng),系統(tǒng)從而產(chǎn)生一個臨時的令牌,代替密碼,授權(quán)第三方應(yīng)用使用權(quán)限。
? OAuth開放授權(quán)為用戶資源的授權(quán)提供了一個安全的、開放而又簡易的標(biāo)準(zhǔn)。OAUTH的授權(quán)不會使第三方觸及到用戶的帳號信息例如用戶名與密碼等,即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權(quán),因此OAUTH授權(quán)是安全的,目前OAUTH的版本為2.0
優(yōu)點
可控姓: 保證了令牌既可以讓第三方應(yīng)用獲得權(quán)限,同時又隨時可控,不會危及系統(tǒng)安全;
方便性: 只要知道了令牌,就能進入系統(tǒng);
重要性: 系統(tǒng)一般不會再次確認(rèn)身份,所以令牌必須保密,泄漏令牌與泄漏密碼的后果是一樣的,這也是為什么令牌的有效期,一般都設(shè)置得很短的原因。
SSO 與 Oauth
SSO
SSO是Single Sign On的縮寫。SSO是在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)。它包括可以將這次主要的登錄映射到其他應(yīng)用中用于同一個用戶的登錄的機制。它是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。
區(qū)別
兩者都是使用令牌的方式來代替用戶密碼訪問應(yīng)用。
SSO :一次登陸
Oauth:一次授權(quán)
OAuth解決的是服務(wù)提供方(微信等)給第三方應(yīng)用授權(quán)的問題;
SSO解決的是大型系統(tǒng)中各個子系統(tǒng)如何共享登陸狀態(tài)的問題。(比如你登錄了百度首頁,那么你進入百度百科,百度貼吧,百度音樂等服務(wù)的時候都不需要重新登錄。)
兩者都是基于分布式系統(tǒng),涉及到多個角色,但是不同的是,OAuth是一種具體的協(xié)議,SSO可以說是一種技術(shù),可以用cookie實現(xiàn),甚至也可以用OAuth實現(xiàn)(雖然不是很好),比如OAuth中的服務(wù)提供方可以充當(dāng)SSO認(rèn)證中心,OAuth中的第三方應(yīng)用也可以是SSO中的子系統(tǒng)。文章來源:http://www.zghlxwxcb.cn/news/detail-839528.html
參考1 參考2 參考3文章來源地址http://www.zghlxwxcb.cn/news/detail-839528.html
到了這里,關(guān)于鑒權(quán)與身份認(rèn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!