iT邦幫忙

3

前端登入方式

  • 分享至 

  • xImage
  •  

這幾天參加了幾場面試,在基礎前端知識的部分,掌握度還可以,不過遇到網路知識的部分,就會答的很吃力,所以這邊針對網路知識的部分做加強,並且記錄一下,並且希望會有幫助到有需要的人

這邊先打個預防針,因為大部分是我整理完文章的理解,所以有任何錯誤,都歡迎留言給我,謝謝

那我們廢話不多說,進主題

常見的登入方式

  • Cookie + Session 登入
  • Token 登入
  • SSO 單點登入
  • OAuth 第三方登入

Cookie + Session 登入

在講 Cookie + Session 登入前,我們應該先來了解一下,為什麼會有這兩個東西:

因為 HTTP 是一種無狀態 (stateless) 的協議,所以每次請求都是獨立的 ,伺服器端無法判斷本次請求和上一次請求是否來自同一個使用者,進而也就無法判斷使用者的登入狀態。

那你可能會好奇,那為什麼要 無狀態 (stateless) 的協議 ?你要想如果我們需要存儲大量的使用者狀態,就會造成很大的伺服器端維護成本,所以如果可以 客戶端、伺服器、資料庫都不去儲存使用者狀態,那不是很棒?所以 無狀態 (stateless) 的協議 就誕生了

為了解決 HTTP 無狀態帶來的問題, Lou Montulli 在 1994 年的時候,推出了 Cookie

Cookie

Cookie 是瀏覽器存放資料的地方,可以存放 session 之類的資料

這邊舉個網路上普遍的例子:Cookie 就是 會員卡,瀏覽器可以透過 Cookie 去知道使用者狀態,就好像會員卡能知道你的購買記錄一樣

簡單來說,就是伺服器透過 Header 的屬性 Set-Cookie,把使用者的狀態紀錄成儲存在使用者電腦裡的 Cookie ,而瀏覽器在每一次發送請求時,都在 Header 中設定 Cookie 屬性,把 Cookie 自動帶上,伺服器就能藉由檢視 Cookie 的內容,得知瀏覽器使用者的狀態

Cookie 雖然說是自動帶上,不過也有失效的部分,後面一點我們會提到

前面有提到 Header 能夠透過 Set-Cookie 把使用者的狀態紀錄成儲存在使用者電腦裡的 Cookie 那我們現在來看一下Set-Cookie 的內容跟一些可客製化的屬性:

  • domain:Cookie 的有效 domain (如果未設定,就會自動綁在執行 Set-Cookie 的 domain 下)
  • path:可以指定 Cookie 只在特定路徑下生效,未設定預設為 '/'
  • Max-Age:有效期限,單位是;當數值為正數時有效,負數時為本次 Session 有效;0 為刪除 Cookie
  • Expires:同上,只是指定的是時間點(如果沒有明確設定的話,就是在關閉瀏覽器前失效)
  • secure:安全性,當這個屬性被設為 true 時,此 Cookie 就只會在「安全的協議」下傳輸,通常為 HTTPS
  • HttpOnly:只能在網路傳輸中使用,當設為 true 時,此 Cookie 就無法在任何 JavaScript 程式碼中取得

Session Cookies,指的是沒有指定 Expires 或 Max-Age 的 Cookies,當瀏覽器關閉時,這些 Cookies 也會跟著消失

取得或是寫入 cookie

// 取得當前的 cookie
console.log(document.cookie)

// 寫入 cookie,myName 欄位寫入 jan
document.cookie = 'myName=jan'

// 寫入 cookie,並加入過期時間
document.cookie="myName=jan; expires=Mon, 04 Dec 2017 08:18:32 GMT; path=/"

// 寫入 cookie,設定 10 秒後失效
document.cookie="myName=jan; max-age=10; path=/"

Session

帳號登錄驗證過後,後端所發的識別證

Session 的儲存大小是與 cookie 共用,利用 session Id 來判定&記錄資料

Cookie + Session 登入

扯了這麼多,回到登入部分,使用 Cookie + Session 登入的流程大概是:

  1. client端發送一個 http request 到 server 端
  2. server 接到 request 後,建立一個 session,並傳送一個 http response 回client端,而這個 response 包括 Set-cookie 的 header,裡面存有sessionID。
  3. 當client端發出第二次 request 後,若 server 給了Set-cookie,瀏覽器會自動在 request 中加入 cookie。
  4. server 接受 request,解析並驗證 cookie,若驗證成功就回傳 response 給client 端;失敗則回除錯誤碼。


圖片取自: https://medium.com/pierceshih/%E7%AD%86%E8%A8%98-session-cookie-%E5%A6%82%E4%BD%95%E5%AF%A6%E8%B8%90%E4%BD%BF%E7%94%A8%E8%80%85%E8%AA%8D%E8%AD%89-4fcf3f044c54

請求沒帶上 Cookie

文章中間有提到 Cookie 雖然是自動帶上的,但其實不保證一定自動帶上,以下三種狀況下,如果有任何一個條件沒有達到的話,Cookie 是不會自動帶上的:

  1. Cookie 的 domain 必須跟瀏覽器相同
  2. 都是http或者https,或者不同的情況下 Secure 屬性為false
  3. Cookie 的 path 屬性必須包含在要發送請求的路徑中,例如: Cookie的path為/test,那麼要發送請求的路徑必須為/test或者/test/xxxx才可以

Cookie + Session 的缺點

  1. 由於伺服器端需要對接大量的客戶端,也就需要存放大量的 SessionId,這樣會導致伺服器壓力過大。
  2. 有 CSRF 的風險

CSRF

CSRF 全名為: Cross-site request forgery,跨站請求偽造的手法就是惡意網站用釣魚手法讓你送出你已經拿到 cookie 的網站請求

這邊使用這篇文章的例子:

  1. 使用者已經登入了銀行網站 ( 拿到 sessionID)
  2. 駭客用社交攻擊手法讓你打開釣魚網站,該網站有偷偷嵌入銀行的 form 表單(例如說轉帳的表單)
  3. 使用者在不知情的狀況下在釣魚網站對銀行送出這個 form 表單 (送出時一併帶入了 Cookie)
  4. 駭客開心收到你的轉帳。

Token 登入

為了解決 Cookie + Session 的 CSRF 或其他諸多問題,我們可以使用 Token 的登入方式

Token 是 server 生成的一串字串,以作為 client 請求的一個令牌。當第一次登入後,server 會生成一個 Token 並返回給 client,client 後續訪問時,只需帶上這個 Token 即可完成身份認證。

Token 登入的流程大概是:

  1. 使用者輸入賬號密碼,並點選登入。
  2. 伺服器端驗證賬號密碼無誤,建立 Token。
  3. 伺服器端將 Token 返回給客戶端,由客戶端自由儲存

Token 登入的優點
伺服器端不需要存放 Token,所以不會對伺服器端造成壓力(是透過解析 Token 並驗證的方式執行)
Token 可以存放在前端任何地方,可以不用儲存在 Cookie 中,提升了頁面的安全性。

JWT

JWT 全名為: Json Web Token,通常用來解決身份認證的問題,JWT 是一個很長的 base64 字串在這字串中分為三個部分別用點號來分隔: Header, Payload, Signature

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

Header
裡面分別儲存型態和加密方法,通常系統是預設 HS256 雜湊演算法來加密
必填欄位

  • alg: 對此 JWT 進行簽章和(或)解密的主要演算法。對於未加密的 JWT,此聲明必須設置為 none。

非必填欄位

  • typ: JWT 本身的媒體類型
  • cty: 內容類型
{
 "alg": "none"
}

Payload
自定義的數據,例如: 用戶資料
具有所附特定含義的權利要求被稱為 registered claims

Signature
檢查碼是為了預防前兩部分被中間人偽照修改或利用的機制 (簽名檢查碼用),是將被轉換成 Base64 編碼的 Header、Payload 與自己定義的密鑰,透過在 Header 設定的雜湊演算法方式所產生的。

JWT 缺點

雖然 JWT 看起來是無敵了,解決了許多 Cookie + Session 的問題,不過還是有缺點:

  1. 使用者可能拿到 JWT 後又修改密碼,這時因為 Authentication 有變動,要讓改密碼前的 JWT 無效,這可以透過 JWT 的 exp(Expiration Time) 去解決
  2. Authorization Header 的確能避免 CSRF,不過因為把 JWT 放到 localStorage 中,就會衍生出 XSS 攻擊,有心人士會將惡意的 JavaScript 程式碼載入到你的瀏覽器中,那麼 JWT 一樣會有被被盜用資源的問題,反觀 Set-Cookie 就有 HttpOnly,可以防止 JavaScript 存取

SSO 單點登入

不知道各位讀者有沒有遇過公司有多個產品,但只需要登入一次,所有產品都會自動登入?這就是所謂的 SSO 單點登入

圖片取自:https://zhuanlan.zhihu.com/p/334720992SSO
流程大概是:

  1. 使用者訪問第一個網站,我們姑且叫他 a.com 下的 pageA 頁面。
  2. 由於沒有登入,則會重定向到認證中心,並帶上回調地址 www.sso.com?return_uri=a.com/pageA ,以便登入後直接進入對應頁面。
  3. 使用者在認證中心輸入賬號密碼,提交登入。
  4. 認證中心驗證賬號密碼有效,然後重定向 a.com?ticket=123 帶上授權碼 ticket,並將認證中心 sso.com 的登入態寫入 Cookie。
  5. 在 a.com 伺服器中,拿著 ticket 向認證中心確認,授權碼 ticket 真實有效。
  6. 驗證成功後,伺服器將登入資訊寫入 Cookie(此時客戶端有 2 個 Cookie 分別存有 a.com 和 sso.com 的登入態)。

不同tab的cookie是共用的嗎?
由於 SSO 的作用就是能在自家產品中,登入任何一個產品後,自由切換到不同的產品,而不必在做多餘登入的動作,這時可能就會有人好奇,那存入的 cookie 是共用的嗎?其實如果兩個 tab 的 domain, 協議(Http or Https), port 都相同的話,cookie 就會是一樣的

OAuth 第三方登入

OAuth 是一個開放標準的 授權協議 ,它允許 軟體應用 代表 資源擁有者 訪問資源擁有者的 資源

白話一點就是:

我們允許並授權當前的應用程式(在這是指 妳即將進入的程式,可能是 Medium 或是 twitter …)有限度的取得我們在 Facebook、Google 或其他平台的相關資訊

從標題:第三方登入,可能有些讀者已經能猜想得到這是什麼樣的登入方式了,相信各位在登入一些頁面時,會跳出一個視窗,問你要不要使用 Facebook 或是 Google 登入


上圖就是使用 OAuth ,他會詢問你是否要使用第三方(Email, Apple 帳戶)登入
OAuth 流程大概是長這樣:

  1. 瀏覽器將使用者導頁至 Google 身份驗證的頁面,並透過 Google 的服務進行身份驗證。
  2. 身份驗證成功後,使用者會被詢問是否同意讓應用程式取得特定的一些資料。
  3. 使用者同意後,瀏覽器將把使用者帶回應用程式當中;使用者也能選擇不同意,那這個流程就在此結束了。
  4. 此時,使用者已經同意,應用程式就能順利前往 Google 存放資料的對應地方,去取得所需要的相關資料。

這邊只是簡單的介紹一下OAuth的流程而已,如果有興趣的讀者,推薦可以讀一下這篇文章

結語

這篇文章篇幅較長,我已經盡量再濃縮了,這邊幫大家整理一下重點:

  1. Cookie 是瀏覽器存放資料的地方,可以存放 seesion 之類的資料
  2. Session 是帳號登錄驗證過後,後端所發的識別證
  3. Cookie + Session 會導致需要存放大量的 SessionId,造成伺服器壓力過大
  4. Token 是 server 生成的一串字串,以作為 client 請求的一個令牌
  5. SSO 是指的是在內部搭建一個公共的認證中心,一但有單一產品登入後,其他產品都會自動登入
  6. OAuth 是一個開放標準的授權協議 ,它允許軟體應用代表資源擁有者訪問資源擁有者的資源

那以上就是今天的文章,希望有幫助到大家,一樣有問題或是有錯誤都歡迎留言給我,那我們下次見,拜拜

文章同步發表到我的 Medium ,有興趣的讀者可以去看看

參考文章:
https://tw.alphacamp.co/blog/cookie-session-difference
https://blog.csdn.net/john1337/article/details/104571244
https://medium.com/pierceshih/%E7%AD%86%E8%A8%98-session-cookie-%E5%A6%82%E4%BD%95%E5%AF%A6%E8%B8%90%E4%BD%BF%E7%94%A8%E8%80%85%E8%AA%8D%E8%AD%89-4fcf3f044c54
https://jimmywei01.github.io/2019/05/14/cookie%E3%80%81session%E3%80%81local-storage%E3%80%81session-storage-%E5%B7%AE%E7%95%B0/
https://5xruby.tw/posts/hello-spa-rails-api-server
https://www.gushiciku.cn/pl/pZ8M/zh-tw
https://blog.kenwsc.com/posts/2023/jwt-vs-session/


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言