跳至主要内容

[web] Session & Cookie

傳統上指稱的 Session 是存放在伺服器上的,Client 的 request 中帶著的 Cookie,這個 Cookie 內包含 session_id 的訊息,server 便可以透過此 session_id 去查找伺服器上 Session 資料表內,找出該使用者的身份為何。

What is the difference between localStorage, sessionStorage, session and cookies? @ StackOverflow

待參考:👍 HTTP Cookie

Set-Cookie:
cookieKey=cookieValue; # key-value pair
expires=Tue, 09 Jun 2020 15:46:52 GMT; # 過期時間
Max-Age=1209600; # 最常有效時間(優先權較高)
Path=/about/; # 只限定作用在某個 path,預設是 "/"
Domain=api.pjchender.com; # 只限定作用在某個 domain
Secure; # 只能在 HTTPS 的協定下傳送此 Cookie
HttpOnly; # 不能透過 Document.cookie 這種 JS 的方式讀取 Cookie
SameSite=Lax; # 包含 Lax, Strict, None,跨站情況下是否要傳送該 Cookie

Expires 和 Max-Age 的設定

  • 當同時設定 expiresMax-Age 時,Max-Age 有比較高的優先權。

Domain 的設定

  • 當不在該 Domain 的環境下,卻針對其他 Domain 設定 Cookie 時會無效。舉例來說,在 pjchender.blogspot.com 中透過 Set-Cookie 試圖設定 Domain=pjchender.github.io 時,會沒有作用,瀏覽器會拒絕這個 Cookie。
  • 一般的情況下,若設定 Domain=pjchender.com 那麼不論所處的 subdomain 為何(例如,info.pjchender.com, dev.pjchender.com)都可以成功設定此 Cookie。但當這個 domain 是列在 Public Suffix List 中時,會有例外的情況,以 github.io 為例,即使我在 pjchender.github.io 這個網域,但因為 github.io 是被列在 Public Suffix List 中,因此將不能設定 Domain=github.io,此 Cookie 設定會無效,並且被瀏覽器拒絕。

AJAX 請求

  • 當 AJAX 發送請求的來源和目標 domain 相同時,瀏覽器會在請求中帶入目標 domain 的 credentials(即,Cookie)。

  • 若來源和目標 domain 不同時,設定的情況下瀏覽器不會把 credentials(即,Cookie)添加到該請求中,除非在 AJAX 的請求中加上 credentials: "include" 的參數,例如:

    fetch('https://www.pjchender.com', {
    credentials: 'include',
    });

    同時在 server 的部分,若想要順利處理此請求,需要在 header 中給予 Access-Control-Allow-CredentialsAccess-Control-Allow-Origin 的設定。

Same-Site/First-Party or Cross-Site/Third-Party cookies

推薦連結

每個 Cookie 都會有一個相關聯的 domain:

  • Cross-site (Third Party):如果這個 domain 和使用者當前網址列上的 domain 不同
  • Same-site(First Party):如果這個 domain 和使用者當前網址列上的 domain 相同

image-20231205095231453

這幾年(2019、2020 年)如果想要使用 Third-Party Cookie,一定要使用 SameSite=None; Secure,但因為 Third-Party Cookies 太常被用來追蹤使用者的 Profile,廣告商利用 Third-Party Cookie,做到 cross-site tracking,也就是廣告商能夠跨站辨別使用者的身分,進而得知使用者瀏覽了那些網站,進一步推測使用者的偏好。

為了提升使用者的隱私權,越來越多瀏覽器禁止使用 Third-Party Cookies,也就是說,即使加上了 SameSite=None 也沒有用。

Google Chrome 預計在 2024 年也開始禁用 Third-Party Cookie,取而代之的是提供了隱私權(可能)更好的幾種不同做法:

  • Partitioned with CHIPS (Cookies Having Independent Partitioned State):這個 Third Party 的 Cookie 只能讀寫在同一個 domain 下的內容,沒辦法跨站讀取,如此來避免 cross-site tracking。適合用在每一個 site 底下都是獨立不需相依辨認使用者的情況。

    • 使用 CHIPS 時,需要搭配 SameSite=none; Secure,缺少的話瀏覽器會自動忽略;另外很重要的是,如果要移除帶有 Partitioned 的 Cookie,SameSiteSecure 也還是要加上:

      // Vanilla
      document.cookie =
      'Foo=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; partitioned; samesite: none; secure';
      // universal-cookie
      cookies.set('Foo', 'bar', {
      partitioned: true,
      sameSite: 'none',
      secure: true,
      });

      cookies.remove('Foo', {
      partitioned: true,
      sameSite: 'none',
      secure: true,
      });
  • Storage Access API:在使用 Third-Party Cookies 前,會先向使用者詢問是否提供權限

  • Related Website Sets (RWS):預先定義好一系列實際有關聯的網站(例如同一個集團底下的不同網站),並提交審核後,如此可以在不向使用者詢問權限的情況下,做到 cross-site tracking。

參考