讓 Subdomain 也可以使用 Cookie

July 11, 2019

Photo by Adeolu Eletu on Unsplash

最近工作上需要實作一個功能,主要是記錄使用者的來源,簡單透過網址上的 query string 作為 cookie 的值,例如像是:https://something.com/?from=twitter 這樣之類的網址,如果你有注意有些文章的分享網址是一大串的,就是有可能在做這些使用者的來源分析之類的。

這次的目的是要在 A 網站先將 cookie 存起來,到 B 網站後再將這個 cookie 讀取出來,在實作的時候,我是直接打開 DevTools 直接新增這個 cookie,確保在 B 網站可以讀取 cookie 並存進 database,直到東西上線後才被提醒資料沒有被成功存入,才發覺我忽略了一件事情 - Cross Domain,也就是跨域這件事。

如果在設定 cookie 時,沒有指定 domain 的範圍,通常就只有該網站可以存取到這個 cookie,在我的場景下,也就是只有 A 網站可以讀取,B 網站是完全讀取不到的,這時候必須在設定 cookie 時加上 domain,以下是我一開始寫的範例:

const FROM = 'instagram';
const MAX_AGE = 24 * 60 * 60 * 30; // 1 Month

const cookie = `from=${FROM}; max-age=${MAX_AGE}; path=/`;

document.cookie = cookie;

我在 cookie 中設定了參數 from,它是一個 key-value,以及 max-agepath

💡 max-age 是設定 cookie 的失效時間,對於舊的瀏覽器可能不支援,可以使用 expires 作為替代;若同時設定 max-ageexpires,則以 max-age 為優先。

透過 domain 參數讓子網域也可以取得 Cookie

在查詢 MDN 文件後,才知道可以透過設定 domain 的方式,讓子網域也可以取得 cookie。

例如我的網域是 jiepeng.com,如果今天我有另一個網站,而它網域是 running.jiepeng.com,那麼,只要我在 domain 的地方設定 .jiepeng.com,就可以讓 running.jiepeng.com 也可以拿到 cookie 了,所以上面的範例可以改寫為:

const FROM = 'instagram';
const MAX_AGE = 24 * 60 * 60 * 30; // 1 Month

- const cookie = `from=${FROM}; max-age=${MAX_AGE}; path=/`;
+ const cookie = `from=${FROM}; max-age=${MAX_AGE}; domain=.jiepeng.com; path=/`;

document.cookie = cookie;

實際案例:twitter

如果你有在使用 twitter 的話,你可以開啟你的 DevTools 觀察一下 cookie 的狀況:

  • 一般網頁
  • 行動版網頁

可以注意到網域都是 .twitter.com

Reference