半熟前端

軟體工程師 / 台灣人 / 在前端的路上一邊探索其他領域的可能性

本部落格使用 Gatsby 製作

本部落格有使用 Google Analytic 及 Cookie

前端

如何判斷兩個網域的擁有者是否相同?

如何判斷兩個網域的擁有者是否相同?

在瀏覽網頁時,我們時常透過 subdomain 來區分服務的內容,例如:

很顯然地,因為 domain name 是 youtube.com,我們可以很快得知這兩個網域都是由 YouTube 所擁有,也因此我們可以信任裡頭的內容,安心瀏覽。那麼我們應該怎麼判斷兩個網域是否屬於同一個擁有者呢?判斷 URL 是否包含 youtube.com 字串嗎?

很顯然地,這並不是一個有效的區別方法,舉例來說:

  • youtube.kalan.dev
  • youtube.com.kalan.dev

這兩個子網域雖然都包含了 youtube 字串,但我們很快就可以得知它並不是 YouTube 所擁有的網域。

因此子網域的判別方式應該由右至左開始找起,而非從左至右。判別子網域對於軟體工程師來說輕而易舉,但對於不懂 domain 運作機制的人來說,透過子網域釣魚容易讓人掉入陷阱。

第二問題來了,從右至左要找幾個部分?以 blog.kalan.dev 來說,domain name 為 kalan.dev,程式碼可以這樣寫:

js
const host = 'blog.kalan.dev'.split('.').reverse().slice(0, 2).reverse().join('.')

然而這並不是一個相當正確的寫法,舉例來說:

  • ebay:www.ebay.co.uk
  • google:www.google.co.uk

如果以剛剛的寫法來看,那麼 co.uk 會是 domain name,www.ebay 跟 www.google 則是 subdomain,所以兩個網站都屬於 .co.uk?很顯然這樣區別是錯誤的,ebay 是 ebay;google 是 google,兩個 domain 屬於完全不同的公司所有。原因在於國家代碼一級網域搭配二級網域也會被當作獨立的 domain name 使用。因此在這邊正確的解析方式是將 google.co.ukebay.co.uk 視為兩個獨立的 host,擁有者也完全不同。

TLD(Top Level Domain)

是時候來談談頂級域名了。像是 .io.dev1.org 等後綴,這些域名都是由 ICANN 管理的,每個人都可以申請自己的網域,像是我的 kalan.dev 就是以 .dev 為後綴組合而成的網域。

Group 25

ccTLD(Country Code top-level Domain)

根據地區也有對應頂級域名可以使用,像是 .tw 或是 .jp。要注意的是有些 country code 與其他二級域名搭配時,也會單獨形成一個網域,像是:

  • www.momoshop.com.tw
  • www.books.com.tw

在這兩個網站當中,momoshop.com.tw 與 books.com.tw 為網域名稱,而 www.momoshop.com.tw 與 www.books.com.tw 則是其子網域。

Group 25 (1)

eTLD(effective top-level domains)

從以上幾個例子可以發現,有些頂級網域可以跟二級網域搭配變成一個網域名稱(例如 kalan.dev),而有些則是兩個域名集合起來變成一個頂級網域(.com.tw),瀏覽器要怎麼知道如何解析呢?這背後的概念是透過維護一個巨大的 Public Suffix List(PSL)列表,在裡頭列出的網域名稱就被稱作 effective top-level domains(eTLD),列表可以在這裡取得。

另外一個常見的名詞則是 eTLD+1,代表有效頂級域名+一個二級域名會形成一個網域,在本範例當中 .com.tw 為有效頂級域名,而 momoshop 則是二級域名。

檢查一下

SameSite 對前端應用的意義

網域的運作機制對於前端最大的意義在於 SameSite2 的判斷,我們想要知道兩個網站是否為 SameSite,因為在 SameSite 的情況下網站的 Cookie 是共享的(在沒有特別設定 header 的情況下)。

因此給定兩個網站 URL,kalan.hacker.comjack.hacker.com,請問這兩個 URL 是否為 SameSite?乍看之下兩個 URL 很像 hacker.com 的 subdomain,但看完剛剛的例子與說明,我們應該先看看 hacker.com 有沒有在 public suffix list 裡才能做判斷。

如果對 cookie 與 Samesite 的討論有興趣的話,也可以參考我之前寫的文章關於 Cookie 與 CORS 的再思考

以 GitHub 舉例

在 GitHub 當中,可以透過 Repository 的設定免費生成 xxx.github.io 的網域 ,像是我的舊部落格:kjj6198.github.io/blog。在這種情況下,我們可不希望每個 xxx.github.io 的 cookie 都可以互相存取。對於這類型的應用來說,我們希望的是每個 xxx.github.io 都是一個獨立的網域,而不是 .github.io 的子網域,透過 eTLD 可以有效解決這個問題,查看 public suffix list 也確實可以找到 .github.io 的存在。

誰可以申請 Public Suffix List?

publicsuffix 的官方文件看起來,只要按照官方的規定發個 PR 就可以了,只是整個流程看起來需要花些時間,而且從過往的 PR 看起來都是人工審核。

談談瀏覽器的地址欄

我的 blog.kalan.dev 在 Firefox 跟 Edge 的地址欄上面的顯示如上圖,上面是 Firefox 的顯示,下面是 Edge 的顯示。

有觀察出來差異了嗎?blog 文字在 Edge 當中顏色和 kalan.dev 是一樣的,但是在 Firefox 當中 blog 的文字比較淡一點。Firefox 的地址欄只會將網域名稱的顏色強調出來,而 Edge 以及 Chrome 則是將網域部分(包含子網域)也一起強調出來。在這個例子當中,透過 Firefox 的地址列我可以很快知道 blog 是 kalan.dev 的一個子網域。

這個差異雖然很小,但是當網域含有 eTLD 時 Firefox 的地址欄功能就相當有用,例如 kjj6198.github.io,由於 .github.io 為 eTLD,所以整個 kjj6198.github.io 是一個網域。

下次如果有人問你兩個網域是不是 Samesite 的話,最好的方法就是打開 Firefox 輸入網址,看看兩個 URL 強調的部分是不是一樣,如果是的話我們可以很有信心地說他們是 Samesite 了!


  1. 額外一提,.dev 是由 Google 註冊與運營的頂級域名,而且強制要使用 HTTPS 才能瀏覽網頁,感覺就算不是開發人員也可以申請。

  2. Samesite 跟 Same origin 是完全不同的概念。

如果覺得這篇文章對你有幫助的話,可以考慮到下面的連結請我喝一杯 ☕️
可以讓我平凡的一天變得閃閃發光 ✨

Buy me a coffee