前言

驗證與授權一直是網站一個很重要的部分,Blazor Server 的專案,和以往的 ASP.NET MVC 專案類似,在這邊比較特別的是 Blazor WebAssembly,因為他是一個在使用者端運作的程式,也就代表著使用者端可以任意修改程式碼,所以驗證相較於 Server 專案是沒那麼重要的

在這一個章節我會在 託管在 .net Core 上的 WebAssembly 實作JWT驗證,由於是 Step by Step 所以這個主題稍微長一些

JSON Web Tokens (JWT)

簡介

這邊簡單的介紹為什麼用 JWT ,在過去許多的專案中使用的驗證機制是伺服器端建立 Session,但是 Session 並不適合在多台主機部署的情況,因為 Session 是建立在伺服器的記憶體內,可是不同機器間記憶體不能互相溝通,所以想要橫向部署時並不是太方便

可以理解成 Session 是客人到櫃檯登記,櫃檯會紀錄客人資訊發行一張票卷蓋上章,下次客人再來時拿著票卷,櫃檯比對有沒有這一發出這一張票卷就知道來的人是誰了

可是今天有兩個櫃檯的時候,我先到 A 櫃檯拿了一張票,下一次走 B 櫃檯時你拿 A 給你的 票, B 櫃檯是認帳的因為他沒有發行著張票卷的資訊

JWT的做法可以理解成,A 和 B 兩者都講好了發行票卷的方法,並載明日並且說好怎麼驗證票卷,當使用者取到了票後,不論走到 A 和 走到 B 都可以適用

JWT 非常適合用在前後端分離的網頁,因為 HTTP 本身是無狀態的,所以每一次來其實伺服器都不認識你,只能透過票卷來辨別使用者的身份

原理

JWT Token 就像是一張票卷,根據 RFC 7519 發行的票卷,可以記載各種各樣的資訊在上面下面是我發行的一份 Jwt Token

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiLlj4Pos73ogIUiLCJuYW1lIjoiSmltIFdhbmciLCJpYXQiOjE1MTYyMzkwMjJ9.vu7fYCUxT5yvuEJTuzZN3W2abrYiAiblQxoVsoZD2lI

Token 可以用 . 拆分成三個部分

用來記錄 alg(演算法) 以及 Token Type(typ)

1
2
3
4
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

乘載資料類型,這邊有一些類型可以在 規格書4.1 參考

1
2
3
4
5
{
  "sub": "參賽者",
  "name": "Jim Wang",
  "iat": 1516239022
}

Signature

在這邊 IThome 就是我加密的 Key

1
2
3
4
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),IThome
)

Header 和 Payload 是資料的部分,第三個 Signature 是用來驗證資料用的

把 Header 和 Payload 做 UrlEncode 後,加上 Key 做雜湊簽名,如果任何一段資料被修改,做完雜湊的結果就會不同導致Token的第三段比對不起來 正確的 如果把這邊第二段的9改成8就會導致新的資料算出來的簽名不同 錯誤的

看到這邊會發現 JWT 本身並不會對資料做隱藏的動作,重點在於可以確保資料的不可竄改性,不可以把機密資料放在 Payload 上,任何一個人拿到 Token 都可以對其做解密查看 Payload

小結

在實作 JWT 時,你的 Private Key 就是驗證正確性以及確保安全性的關鍵,所以千萬要確保有足夠的安全性,下一章會用 .net Core 來發行一個 JTW 並且讓託管的應用程式去驗證發行的 Token