現(xiàn)在隨著客戶端的多樣化、前端的不斷發(fā)展闰蛔,傳統(tǒng)的基于cookie的會(huì)話控制限制越來越多悟泵。cookie的跨域問題,移動(dòng)端native app 對(duì)于cookie支持的缺失挑童。今天就來看下另一種解決方案累铅。
用戶認(rèn)證的本質(zhì)
用戶認(rèn)證分為會(huì)話控制(authentication)和權(quán)限控制(authorization)。要實(shí)現(xiàn)會(huì)話控制站叼,就需要一個(gè)身份認(rèn)證的過程:
1.客戶端提供認(rèn)證憑證娃兽。eg:username password
2.服務(wù)器核對(duì)。
3.核對(duì)失敗則返回失敗信息尽楔。核對(duì)成功則返回成功標(biāo)識(shí)投储,傳統(tǒng)的方式是使用session,設(shè)置客戶端cookie阔馋。
4.客戶端請(qǐng)求需要認(rèn)證的網(wǎng)址玛荞。傳統(tǒng)的方式是由瀏覽器自動(dòng)發(fā)送cookie到服務(wù)器端,服務(wù)器端核對(duì)sessionid呕寝。
基于token的認(rèn)證系統(tǒng)
優(yōu)點(diǎn)
基于token的認(rèn)證系統(tǒng)解決了什么問題呢勋眯?
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX calls to any server, on any domain because you use an HTTP header to transmit the user information.
Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contanined entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Decoupling: you are not tied to a particular authentication scheme. The token might be generated anywhere, hence your API can be called from anywhere with a single way of authenticating those calls.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a secure API (you have to deal with cookie containers). Adopting a token-based approach simplifies this a lot.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to <iframe>
your site, generate a POST request and re-use the existing authentication cookie because there will be none).
Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database) is likely to take more time than calculating an HMACSHA256
to validate a token and parsing its contents.
Login page is not an special case: If you are using Protractor to write your functional tests, you don't need to handle any special case for login.
Standard-based: your API could accepts a standard JSON Web Token (JWT). This is a standard and there are multiple backend libraries (.NET, Ruby, Java,Python, PHP) and companies backing their infrastructure (e.g. Firebase, Google,Microsoft). As an example, Firebase allows their customers to use any authentication mechanism, as long as you generate a JWT with certain pre-defined properties, and signed with the shared secret to call their API.
可以看到token解決了以下問題
- 跨域。ajax設(shè)置"Authorization header" and "Bearer。
- 狀態(tài)無關(guān)客蹋。天然適合restful services塞蹭。
- CDN。 專注api讶坯。
- 解耦番电。token可以隨時(shí)生成,隨處驗(yàn)證辆琅。
- 移動(dòng)適用漱办。移動(dòng)端cookie支持不好。
- CSRF涎跨。這個(gè)需要具體情況具體分析洼冻。
- 性能。連接數(shù)據(jù)庫(kù)查詢session比對(duì)token進(jìn)行解密更費(fèi)時(shí)間隅很。
- 標(biāo)準(zhǔn)化撞牢。 JSON WEB TOKEN (JWT) http://jwt.io/
區(qū)別
缺點(diǎn)
token存儲(chǔ)、傳輸叔营。
- 對(duì)于reftful 客戶端屋彪, 將其設(shè)置成GET或POST參數(shù)即可。
- 對(duì)于傳統(tǒng)web绒尊⌒蠡樱可存儲(chǔ)在cookie里由瀏覽器自動(dòng)傳送,會(huì)有跨域問題婴谱。
- 或者存儲(chǔ)在localsotrage里, 或者url里蟹但,或者放在頁面里。需要用js手動(dòng)取出谭羔,拼接到url里华糖。這會(huì)加大工作量。適用范圍有限瘟裸。
- 利用"Authorization header" and "Bearer客叉。
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4
Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSIsImVtYWlsIjoiam9obkBkb2UuY29tIiwiaWQiOjEyMywiaWF0IjoxNDMwMDI2MzI0LCJleHAiOjE0MzAwNDQzMjR9.wODsE0vHiGr8RruRppJ79JKqH_Fi_2QUBxNJDzM_nfY
Connection:keep-alive
Host:localhost:8080
If-None-Match:W/"e-87842b1a"
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
總結(jié)
本質(zhì)上cookie和token在客戶端的方式并沒有區(qū)別。都是提供了一種認(rèn)證信息傳輸?shù)姆绞健?/p>
請(qǐng)關(guān)注后續(xù)文章_