# JWT(上)- Session, Cookie 差別與概念 ## 前言 在寫登入系統的時候都會遇到一些驗證的問題,登入後怎麼確保使用者個資不會被篡改?還有怎麼確定是不是原本的使用者?確定資料有沒有被篡改?方式有很多,舉凡session, cookie等都是常用的驗證機制,本篇將為大家介紹上述認證機制的差異,以及JWT的運作流程。 ## Session和JWT是什麼? ### 什麼時候用到? 當我們登入一個網站的時候,如果關掉再打開就要重新登入,使用者當然會覺得很不方便,所以需要一個像是便條紙的功能,貼在使用者的網站瀏覽器上,下一次使用者又打開網站的時候,系統會先去看便條紙上有沒有東西,如果有紀錄使用者id或是其他資料就代表之前登入過了,如果沒有才會要求重新登入。 ### Session 和 jwt 兩者功能其實非常類似,都是將資訊儲存起來,讓使用者不用每次都要重新登入,或是記錄一些動作,前者像一個會員卡,上面只有編號,後端確認過編號後才會從資料庫中尋找隊員卡編號對應的資料,後者就像前面提到的便條貼,把所有的東西寫在上面存在前端,後端可以直接從便條貼上判斷資料有無錯誤,並且回傳對應的資料。 ## JWT 機制 JWT 的全名是 JSON Web Token,是一種基於 JSON 的開放標準(RFC 7519),它定義了一種簡潔(compact)且自包含(self-contained)的方式,用於在雙方之間安全地將訊息作為 JSON 物件傳輸。使用者登入後發送一個要求到後端,後端產生一個JWT後回傳前端,並儲存在瀏覽器的在Local Storage中,前端要取得資料時,將JWT發送到後端,讓伺服器判斷有沒有被修改,認證成功就會把資料回傳給前端。  ### 組成 透過(.)連接三個Base64編碼的字串,分別是: - Header:包含兩個欄位Token得種類和雜湊演算法 ``` { "alg": "HS256", "typ": "JWT" } ``` - Payload:存放需要的資訊(例如使用者id) - exp和iat代表 token 到期和啟用的時間 - payload內可以自訂要放的資訊 ``` { "payload": { "user_id": 3, "user_name": "hello world", }, "exp": 1696532042, "iat": 1696528442 } ``` :::info :warning: payload中不要存放敏感性或機密資料,因為payload是明文,可以輕易被看到,jwt的重點是不可篡改性,而不是加密! 如果真的需要加密資訊,可以考慮使用AES對稱加密法來實作~ ::: - Signature:編譯後的 Header、Payload 與密鑰透過雜湊演算法所產生 ``` HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-secret ) ``` :::info :writing_hand: your-secret是加密的鑰匙,通常存在後端,比較不容易被他人取得,一旦洩漏別人就可以輕易產生jwt了啊! ::: ### 編碼 將上面三個部分分別用Base 64編碼,並且用 . 分隔,就可以得到專屬的jwt了! ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ``` 想要更快解密jwt可以點進[JWT 網站](https://jwt.io/),只要把jwt貼到上面就會自動幫你用base 64 解碼,由此可知放在上面的東西可以容易被看到的!  ### 認證 回到前面便條紙的例子,現在知道有JWT的便條紙且上面又有寫字,但問題又來了,怎麼確保便條紙上面的東西沒有被別人用橡皮擦或立可白修改過呢? 前面有提到第三部分Signature是由header和payload搭配密鑰產生的,換言之要是payload有被修改過,Signature的值也會不一樣,後端解密的過程中藉此來判斷有沒有被修改過!如果後端能透過密鑰解碼成功,前端使用者就可以直接拿到資訊,如果失敗就代表token已經被竄改了,因此不需要再和資料庫連接比對是否是對的token,減少伺服器本身的負擔,這種驗證方式也稱為無狀態驗證。 ## 總結 總之Session和JWT各有好壞,沒有哪一個是絕對好的,還是要依自己的需求而定,因為筆者比較常用js寫前後端,再加上大部分的都用restful api所以主要以jwt為主,有興趣的人可以再看看下一篇 [JWT(下)- 實作認證 React, Node.js](https://hackmd.io/@emmmmmma/rynNZO2g6) 了解實際的應用! ## 參考 - [JWT(JSON Web Token) — 原理介紹](https://medium.com/%E4%BC%81%E9%B5%9D%E4%B9%9F%E6%87%82%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88/jwt-json-web-token-%E5%8E%9F%E7%90%86%E4%BB%8B%E7%B4%B9-74abfafad7ba) - [你的網站是怎麼管理登出登入的呢:Cookie-Session驗證和 JWT驗證機制的差別](https://medium.com/rae-lee/%E4%BD%A0%E7%9A%84%E7%B6%B2%E7%AB%99%E6%98%AF%E6%80%8E%E9%BA%BC%E7%AE%A1%E7%90%86%E7%99%BB%E5%87%BA%E7%99%BB%E5%85%A5%E7%9A%84%E5%91%A2-cookie-session%E9%A9%97%E8%AD%89%E5%92%8C-jwt%E9%A9%97%E8%AD%89%E6%A9%9F%E5%88%B6%E7%9A%84%E5%B7%AE%E5%88%A5-50f60f4d5952) - [用户认证:基于jwt和session的区别和优缺点](https://zhuanlan.zhihu.com/p/108999941) - [JWT tokens and security – working principles and use cases](https://www.vaadata.com/blog/jwt-tokens-and-security-working-principles-and-use-cases/)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up