KK 的 Web 實驗室(Day23–27)

Chunhao Weng
16 min readOct 14, 2020

Plus Ultra Prominence Burn

這純粹是自己不知道為什麼想做的事情,紀錄一下 KK 的生命旅程。

Web 實驗室資源:

Youtube

Facebook

以下為 KK 課程內容的文字紀錄,我本人不是KK。(重要)

影片開始。

27 成為看起來很強的後端:JWT 跟 Session 怎麼組合?

KK 永遠在超越自已

上一篇 KK 老師花了很大的篇幅描述結合 Session /CookieJWT 的方式。

暫稱為 JWT 2.0

那既然需要驗證 Token 然後再做 JWT,為何要把兩邊的缺點結合在一起?

先來複習一下。

JWT 會遇到的問題

JWT 模式

前面提過,原本 JWT 模式的缺點就在「儲存方式」

使用上一個影片介紹的 In-Memory 方式 將 token 存在變數裡,使用者只要在瀏覽器按下重整,Memory 釋出後就會被登出。

所以,沒有時間做其他機制的時候,就直接存在 Local Storage 吧。

Session / Cookie 會遇到的問題

Session / Cookie 模式

當 Client 打一個 /login 給 Server,會拿到一個 Cookie 紀錄 sid 。

而接下來的「每次」執行,不論下單、看東西…,所有行為 Server 都需要跟 Session Store 做溝通,通常會使用 Redis 這樣快取型的資料庫。(KK 老師說之後會再介紹)

一個使用者還好,但當使用者很多的時候,這個資料庫就需要越來越大。

在中心化管理下,擴充的時候也只能「垂直擴充」,也就是只能越開越大台的伺服器,無法用好幾台低階伺服器去「水平擴充」。

因此當網站流量不大,如:個人部落格,可能一個 Session Store 就夠了。

比較大的流量,如:電商網站,管理起來就會比較有挑戰性。

所以要用 JWT 或 Session/Cookie?

通常取決於「實作方式」。

如果是「純靜態網頁」,前端(使用 React、Angular)、後端分離,用 API 呼叫時,就很「適合用 JWT」

因為靜態頁面不用透過伺服器渲染,可以放在內容傳播網路 CDN 上(https://en.wikipedia.org/wiki/Content_delivery_network)。

此時 Static(靜態網頁)和 JWT Stateless 狀態就可以完美搭配。

(感恩前面的課程,順利聽懂 static 跟 stateless 這兩個單字 XD)

如果是「透過 Server 去渲染 Browser 」,也是就是 SSR (Server-Side Rendering)這種情形就很「適合用 Session / Cookie 模式」https://developers.google.com/web/updates/2019/02/rendering-on-the-web

可能會寫某些框架,如:Express、Python 的 Django 或 Flask 、或用 PHP 直接渲染 HTML。

JWT 2.0 (JWT 結合 Session / Cookie)的模式是如何優化這些問題?

解決頻繁溝通的問題

這個模式在 /login 的時候拿到 token ,並在 /refresh-token 的時候才跟 In-Memory 做驗證。

而 /refresh-token 拿到的 auth token 普遍效期約 15–60 分鐘(看應用程式而定,如:網銀可能縮成 5 分鐘),因此只要在時限內都在 Memory 內,所以不用一直去做 refresh-token 。

保有 JWT 平行化(Stateless)的特性

這個模式允許我們開非常多個 Server 大量產生 auth token。

如何防止 /refresh-token 被偷走?

auth token 是短時間的

解決方法跟 Session / Cookie 很像。

在 Server 回傳的 Header 裡面的 Set-Cookie: 除了設定 HTTPOnly ,我們會設定一個時間條件,例如:使用 Max-Age : 30 days 。

而 /refresh-token 並不會被經常更換。

通常在做 JWT 2.0 這樣的模型時,會有個網頁介面,上面有按鈕寫著「更新 Refresh Token」。

我們在登出的時候有個 /logout 登出的 API ,會幫你把 Refresh Token 註銷掉,讓全站登出(全裝置登出)。

而雖然 auth token 在 In-memory 裡面,auth token 是短時間的,所以最慢也是等 auth token 的效期結束,就會把全部裝置登出。

目前沒有辦法達到即刻所有人登出,JWT 2.0 這個方式結合了 JWT 和 Session / Cookie 的各種好處也降低了他們的風險。

而這個模型是目前業界普遍認為比較好的方式。

(KK 說影片底下會附上國外網站連結,但目前還沒看到 lolll 再去問問他)

28 成為看起來很強的後端:串接第三方登入-OAuth2

OAuth2

這個影片要來談談另外一個第三方登入模式: OAth(有非常多版本,目前用的是OAth2的規範。)

OAuth2 的機制,一樣從瀏覽器出發。

網頁頁面有個 FB 連結

通常會看到一個 Facebook 或 Google 的超連結按鈕(一個 HTML Anchor Element) 。https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a

點下去連到網址(以 Facebook 為例)之後,習慣性會彈跳出一個新視窗,也可能會直接把當下的視窗換掉。

連到另外一個 FB 頁面

這時你就會看到一個 Facebook 的網址以及畫面。(如果畫面正確但網址長得很像但是錯誤,如:網址字母 o 改成數字 0,你可能要被釣魚囉)

確認正確,就可以放心地填寫帳號、密碼。

填寫帳號、密碼

登入之後,Facebook 就會幫你導向。

Hawks 幫 Endeavour 導向
OAuth 幫網頁導向

因為OAuth 會要求帶一個 redirect 的網址,導回原本網站,或導去別的網站。

(網址僅作為舉例用,各種第三方服務會有自己的網址設定)

OAuth 的實作方式

通常實作方式有兩種:Authorization Code 或 Access Token 。

以 Authorization Code 模式為例

當導向別的網站時,跟 Access Token 的差別是,Authorization Code 需要多做一個步驟

發出的Request 帶 code=foo 跟 Facebook 拿一個 token 回來,然後再用這個 token 跟 Facebook 要資料(如:使用者 email)。

Authorization Code

以 Access Token 模式為例(紅色線條)

當導向別的網站時,直接帶 token就能跟 Facebook 要東西(如:使用者 email)。

現在比較多傾向用 Access Token 的模式。

Access Token

各種參數怎麼帶?

在 redirect 的網址後面設定 type

Redirect 的時候,根據第三方登入支援哪種模式,可以用 type 選擇要用 Authorization Code 或 Access Token 。

參數 scope 決定拿什麼資料

也可以在一開始 Browser 點擊的時候,帶參數 scope 。(也可能是其他名稱,要看第三方服務設計)

假設想要拿到使用者的 email 或 profile ,在跳出 Facebook 的登入網址時,就會告知使用者這個服務想要獲得的資訊,讓使用者決定是否要提供這些資訊。(或是允許行為,如:是否同意讓這個服務幫你發文章…)

經典面試題

這裡是重點中的重點

面試的時候,可能被問到 OAuth 要做在前端還是後端?

現在重點來到 KK 老師指的這個地方,這個使用者登入之後的「接收方」到底是什麼。

OAuth 作在「後」端

OAuth 選擇導向時,會要求帶一個 redirect 的網址。

我們可以選擇導去別的地方做,如下圖自己(前端)網頁網址為 www.example.com ,而 redirect 導向去(後端) api.exmaple.com

接著再用 301 轉址回去前端頁面。

OAuth 作在後端

優點:安全性比較好。

一來,可以用白名單限制誰被允許做登入。

拿到 token 之後的所有操作都在後端,也不會被 Client 端看到。

缺點:需要301轉址回前端頁面。

OAuth 作在「前」端

我們可以選擇導回原本頁面去做後面的 Request。

優點:不用多開一個 endpoint 。

(什麼是 endpoint?https://stackoverflow.com/questions/9807382/what-is-a-web-service-endpoint)

缺點:token 會碰到 Client 端,就有機會被使用者帶走。

一個仍然不太安全的解決方法是,在 Client 端用 Memory 的方式去儲存。(不使用 Local Storage)

結論

實作 OAuth 機制如果有後端人力,KK 老師會建議放在後端上。

29 成為看起來很強的後端:網路概念總結

收納空間充足

突然畫面一轉,來到一個室內空間,不太確定是哪裡,而且收音品質改變了。

KK 老師這個房間內收納空間相當驚人,光是後方兩個置頂的衣櫃,我這輩子可能都放不完。

網站五大面向

這個系列,KK 老師一開始跟我們分析網站的五大面向,交付、權限、運算、資料、儲存。

第一天的內圈五大面向

舉例來說,這些網站都有使用網頁或 API 不同的交付方式。

可能有不同的運算方式,例如遊戲類網站會用 WebSocket 來進行對接。

有些使用雲端儲存、有些使用本地端、有些使用關聯式、非關聯資料庫。

其實看到這邊開始在想,這是不是試上課程…

畢竟 IT邦幫忙鐵人賽也只有 30 天。

我們繼續看下去。

Client 到 Server 的種種

過去這個月,這一系列影片,KK 老師詳細說明從 Client 端到 Server 端整個流程,透過 DNS 進行解析,變成 IP,經過 Proxy 跟 Router ,最後到達硬體 Server 。

透過 Reverse Proxy (Nginx)的方式去進行請求轉換,如果有預算就可以用 Load Balancer 來分散在不同機器,進行擴充。

進去之後會有 Web Server (PHP、Node.js 的 Express、Python 的 Flask 或 Django…等)。

接著談實際怎麼運作(目前常見的 TCP/IP 四層架構)。從應用層、傳輸、網路、實體層。談了網路協定(規範),例如應用層的各種通訊協定(HTTP、TELNET、FTP、SMTP),也對 HTTP 著墨不少。比較沒有談到 TCP 跟 UDP ,這個部分大家可以自行 Google )https://stackoverflow.com/questions/5330277/what-are-examples-of-tcp-and-udp-in-real-life

HTTP 的格式,分成 Header 跟 Body

Header 內放了 Metadata ,包含要傳到哪裡、路徑是什麼、host 或 path 等等,也談到 URL 的格式。並且討論到裡面如何定義 domain 、接受什麼格式、權限如何帶過去…等。

Body 談的是帶過去的格式,例如 JSON 的格式、 HTML、CVS、純文字…等。

大家如果都不記得了,可以回去重看影片。

30 成為看起來很強的後端:權限總結

權限驗證的部分, KK 老師談了 API Key 模式、Basic Authentication、JWT、Cookie / Session 、OAuth 這幾種方式。

當然還有其他新的權限或自訂的方式,但也都是這些基礎的變化型,例如:把放 Header 的內容放 Body、用別的方式產生 token…等。

容易搞錯的 Authentication 跟 Authorization

權限分為 Authentication (可不可以) 跟 Authorization (什麼程度),了解什麼樣的人可以進行什麼樣的行為、得到什麼樣的資料或服務。當時 KK 老師用學生證的例子說明。

接著,權限驗證分為 Client 端和 Server 端,有 Client to Server (碰到人就是麻煩) 和 Server to Server (躲在防火牆或白名單後面)。

權限驗證又分為三種類型:Event-based (一次性驗證)、Time-based (時效性驗證)、Static (靜態驗證),這些在 API Key 跟 Basic Authentication 都會遇到。

API 走的是 Header 放 x-api-key ,是自定義的,屬於Static 模式比較多,主要看應用情境來決定。

Basic Authentication 用的 Header 是 Authorization:basic ,這個 token 是透過 Base64 (因為可能有不合法使用的字元)把使用者帳號、密碼串在一起編碼,一樣屬於 Static 模式。

JWT (JSON Web Tokens)提到,Header (用什麼方式進行 token 驗證與加密)、 Payload (放 data 的區塊,注意不要放機密資料)、 Signature (驗證中間 Payload 是否正確、有無被竄改)。

(無意間看到這個 https://jwt.io/introduction/

保護這些資料的機制,如:雜湊(單向)、加密(雙向+鑰匙)、編碼(雙向),也有談了不少。

之後影片也談到 JWT 只要有一把 secret 就可以做到 Stateless的驗證。

Session / Cookie 說明不會用 session-based cookie 的方式去儲存資料,而是用 sid (Session ID)存起來。這些資訊會被存在 Session Store ,只要前端有 sid 通過驗證就能拿到資料。

那為了解決這個 sid 可能會被偷走,就可能透過 Server 把 sid 註銷掉。

也可以利用 Persistent Cookie (有設定時效性),而一般 Cookie 瀏覽器關掉就消失了。

JWT 和 Session / Cookie 的各種問題和結合,KK 老師也在前幾週(包含這一篇)裡面做長篇幅的討論。

最後談到 OAuth 如何做第三方登入的實作,可以往上滑直接再次複習。

最後 KK 老師,留下一個問題給大家:

「平常講的帳號、密碼註冊登入,跟這幾種模式差別在哪裡呢?」

有機會可能會再拍影片,不過 KK 爆炸忙啊…

31 成為看起來很強的後端:Web 之路怎麼走

椅子有塑膠套

一開始以為是鏡頭一直在前後移動,創造某種效果,結果發現只是 KK 老師自己用椅子滑前滑後…。

這個影片主要來談談,如果想走 Web 要怎麼選擇之後的方向。

「前端」開始 Web 之路

如果是正準備要踏入寫網站這個領域,最容易就是從前端靜態畫面開始。

因為不需要租主機、管理雲端,可以直接在電腦裡面做出一個頁面。

做出來之後,就算是純靜態網站,還是需要 host 在某個地方。

KK 老師介紹一個常見的網頁空間:Netlify https://www.netlify.com/

如果只會寫前端,也能輕鬆部署網站。

接下來就可以開始碰 CSS 、 SASS https://sass-lang.com/ ,增加網站豐富度。

那如果想讓網站看起來更專業,可以做微動畫,也就是滑鼠滑到按鈕可能有些小動畫,就會看起來更厲害了。

如果不想往酷炫方向走,而是想走更多資料處理的話,就能從「前端設計」慢慢往「前端工程」。

這時候重視的就是「資料流」的處理。

例如:電商網站從加入購物車到結帳過程,換頁、更改數量…等,怎麼讓資料傳輸更順暢、資料不漏、怎麼做 Cache (快取)減少跟後端傳輸的次數,像這些都是前端工程在做的。

另外一個部分著重在「共用性」,也就是各種元件怎麼更好的重複使用。

自然而然就會碰到不少前端框架,如:Angular 、 React 、 Vue…等等。

如果想做視覺效果、動畫的話,就往「前端設計」走。

如果想多做資料處理或邏輯,就往「前端工程」走。

那「後端」呢?

如果想要讓別人不知道你在幹嘛(KK 老師神比喻)可以往「後端」走。

「後端」通常處理的都是一些 API 的建置、如何拿資料、設計穩定的後端、串接第三方登入…等等。

很重要一點:後端工程是被公認沒事看起來很廢,網站出事才會出現,有點吃力不討好。

不過畢竟是苦力活,薪水可能也會好一些。

只是出事的時候,常常都是後端出問題。

前端做出一點改變,大家(老闆、投資人、其他人、不知道你在幹嘛的人)就會很有感覺。

往更「後端」走的 DBA (Database Administrator)

DBA 專門建置高可用性的 DB 、思考如何讓吞吐量增加(可以有更多 Request)、設計資料表讓後端擴充應用…等。

還有什麼跟後端有關?

跟架構比較有關的,例如要建置幾台伺服器、幾台資料庫、什麼樣的系統架構、放 AWS / GCP / 自己的主機…等等。

這些都是透過「架構師」來實作,如果是做系統的就稱為「系統架構師」(System Architect),也有人稱為「解決方案架構師」。

也有一種不只是做軟體的架構師,可能會涉及業務端、行銷端、客服…等的架構。

這樣的角色就更需要有好的溝通能力、了解商業邏輯…,通常都是由外部顧問進來,必須技術底子夠好也涉略許多。

KK 給的建議:不管打算在哪一邊深耕,理想上都能多多了解另一邊的人在做些什麼。

感覺這一系列快要告一段落,有點感傷。

大家有興趣請直接去 Web 實驗室的 Youtube 跟 Facebook 社團吧。

Web 實驗室資源:

Youtube

Facebook

Chunhao Weng
Chunhao Weng

Written by Chunhao Weng

Random notes for personal use.

No responses yet

Write a response