前面不管是在提到HTTP這個應用協定或是REST的風格,都有提到無狀態(stateless)這個特性。
這個特性其中一個目的是希望可以將每次的request都隔離,讓各request不用依賴其他的請求,僅依靠自己單個請求身上所帶的資料完成目的。
但我們回想類似FB, Google,有許多服務的商業模式都是以「會員制」作為基礎,那我們該如何在維持無狀態的特性下,實現這樣的會員制,讓伺服器「認得」請求呢?
今天就會談到這個部分: 「驗證Authenticate」。
其實不管是哪種驗證過程,最終的目的就是要讓伺服器可以「認得」你是誰。
不過「認得」這個字眼實在太過哲學。
想想,如果有一天你已經7, 80歲,突然有個陌生人說他是你的某某國小同學,你該怎麼認得出來是他呢?
最終我們憑藉認得一個人的方式大概分兩種:
根據不同情境其實這兩個概念可以講出的東西可能有點不太一樣。
比如看電影的時候,門口的人看的是門票,他相信的是,只有當事人才會那個座位的電影票,所謂的認票不認人。
回到程式這邊,不知道腦筋有沒有開始自動分類常見的驗證機制?
這兩個類別可能會重疊,比如,伺服器會記錄你的電話號碼,並且在你請求時發送一次性密碼。
概念大致如此,我們實作上一般可分為兩種驗證策略(註1)。
註1: 大部分的驗證策略其實是一種「約定」,這指的是,我們通過一種有共識的做法減少溝通鎖需要的成本。
這是一個透過Header來進行驗證的策略,你可以想像你每次要進到一間店裡,都得告訴他你的帳號跟密碼才會放行。
Authorization: Basic <value>
WWW-Authenticate: Basic realm="<value>"
base64(username:password)
Authorization: base64(username:password)
從上面的流程我們可以整理出Basic Authentication的一些原則
Authorization: Basic <value>
放置待驗證資料(每次請求都會放)WWW-Authenticate: Basic realm="<value>"
與client告知結果。相較於Basic Authentication把用戶名稱及密碼帶在每次request上,Token Based Authentication則是改將一個名為Token的資訊帶在每次request上以代替前者。
Token是什麼呢?指的是一段由server提供給client端以作為驗證身分的字串。
你可以想像你走進店裡的時候,先用「某種方式」讓警衛認得你,而後警衛就念給你一串無意義的字,告訴你在一段時間內,可以不用用前面的方式進到店裡,念給他那串字就可以。
Authorization: <method> <value>
相對於使用Basic Authentication安全,主要是避開每次request都需要帶上沒有經過雜湊或加密的username和password。
以前面的例子來說,你每次都跟警衛講用戶名稱跟密碼,會不會哪天就被聽到了?
透過一些加密的方式,可以讓token本身帶有資訊可以被client解析。
跟前面可帶資訊有關,透過帶著過期的資訊讓資料在指定的時間無法在被使用或拋棄。
這兩個的比較可以參考以下
Appendix C. Relationship of JWTs to Simple Web Tokens (SWTs)
Both JWTs and SWTs [SWT], at their core, enable sets of claims to be
communicated between applications. For SWTs, both the claim names
and claim values are strings. For JWTs, while claim names are
strings, claim values can be any JSON type. Both token types offer
cryptographic protection of their content: SWTs with HMAC SHA-256 and
JWTs with a choice of algorithms, including signature, MAC, and
encryption algorithms.
-- JSON Web Token (JWT)
概要的意思是:
稍微介紹一下目前比較常見的JWT的結構跟製作流程:
包括: Header, Payload, Signature,這三者會以(.)做分隔
圖片來自JSON Web Tokens
base64(Header)
baser64(Payload)
base64(Header)
及baser64(Payload)
使用secret做雜湊,參考下方虛擬碼// Signature虛擬碼
HMACSHA256(base64(header) + '.' + base64(payload), secret)
稍稍了解了有關於驗證的知識,略過了關於cookie、session的概念,以及基於token延伸出的OAuth,有興趣可以再去找相關資訊。
那就這樣啦,明天見~
此文章同步發表於部落格,歡迎來逛逛~
User Authentication: Understanding the Basics & Top Tips
Token Based Authentication
HTTP基本認證
深入理解JSON Web Token系列1:JWT的历史
JWT