web 發展迅猛,技術日新月異層出不窮,web 的安全性同樣是一場持久的攻防戰。而 HTTPS 的普及,為 web 通信構建了更加良好和安全的根基。 ...
這篇文章首發於我的個人網站:聽說 - https://tasaid.com/,建議在我的個人網站閱讀,擁有更好的閱讀體驗。
這篇文章與 博客園 和 Segmentfault 共用。
前端開發QQ群:377786580
這篇文章是基於我在遷移 https://tasaid.com 的時候,和在公司跟進部署 HTTPS 的一些經驗所編寫。收錄在《Said - 從 HTTP 到 HTTPS 》系列:
部署到 HTTPS 會發生什麼
HTTP 協議和 HTTPS 協議是不相容的,即 HTTPS 和 HTTP 是不可互相訪問的 (混合資源),當 HTTPS 頁面中包含 HTTP 內容的時候,瀏覽器會向用戶拋出警告,這個網頁是加密的,但是卻包含不安全的元素,即混合資源 (Mixed Content)。
隨著 chrome 的 安全計劃,今後以下的 API 只能在 安全環境 中使用:
- Geolocation - 獲取用戶地理位置
- Devicemotion / orientation - 設備方向和運動信息
- Encrypted Media Extensions/EME - 加密媒體擴展
- getUserMedia - 採集攝像頭/音頻/屏幕信息
實測中,當前獲取用戶地理位置 API navigator.geolocation.getCurrentPosition
已經只能在安全環境 (可以理解為 HTTPS 環境)中使用,在chrome下,非安全環境使用該 API 會顯示警告:
getCurrentPosition() and watchPosition() no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
做哪些事
自適應協議資源路徑
傳統的資源路徑會一般會寫成絕對路徑和相對路徑:
<img src="/static/bar.jpg"/>
<img src="http://tasaid.com/static/bar.jpg" />
絕對路徑的資源建議使用 //
語法讓它相容 HTTP/HTTPS,//
語法表示這個資源的訪問協議和當前頁面保持一致,如果當前頁面是 HTTPS 的,則會採用 HTTPS 協議訪問,如果是 HTTP 的,則使用 HTTP 協議訪問。
<img src="//tasaid.com/static/bar.jpg" /><!--https://tasaid.com 中會訪問 https://tasaid.com/static/bar.jpg-->
非同步請求
相對路徑下的非同步請求沒有問題,絕對路徑的請求會有問題:
$.ajax('http://tasaid.com/user/get')
如果請求的 url 是相容 HTTPS 的話,則可以在 HTTPS 環境下使用 https://
訪問,否則需要伺服器做一個 HTTPS包裝跳轉,將原 url 的請求在自己的伺服器做一層轉發,表單提交同理。
$.ajax('/httpsRedirect?url=http%3A%2F%2Flinkflys.com%2Fuser%2Fget')
iframe
iframe 只能是被嵌入的 url 也同樣支持 HTTPS,目前本人並未找到合適的方案。當然如果你們服務端真心 NB 的話也可以像某大型搜索引擎一樣把需要內嵌 iframe 的站點抓到自己的伺服器上。
HTTP嚴格傳輸安全協議
HTTP 嚴格傳輸安全協議( HTTP Strict Transport Security,簡稱 HSTS )是 互聯網工程任務小組 (Internet Engineering Task Force,簡稱IETF) 發佈的互聯網安全策略,後者負責互聯網標準的開發和推動。網站可以選擇使用 HSTS 策略,讓瀏覽器強制使用 HTTPS 協議訪問。
為什麼要強制訪問呢? 因為傳統的 HTTP 跳到 HTTPS 都依賴服務端 301/302 跳轉,例如訪問 http://tasaid.com
跳轉到 https://tasaid.com
,而這次強制跳轉的通信,是基於 HTTP 的,所以是可能被劫持的。
設置 HSTS 之後,瀏覽器會在本地替換協議為 HTTPS 然後訪問伺服器,而不用再依賴伺服器跳轉,可以更多的減少會話劫持攻擊。
HSTS 是一個響應頭,只能用於 HTTPS 響應,HTTP 環境下會忽略掉這個響應頭:
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]
參數 | 釋義 |
---|---|
max-age | 指定的時間內 (單位是秒),網站必須使用 HTTPS 協議來訪問 |
includeSubDomains | 子功能變數名稱也必須通過 HTTPS 協議來訪問 |
preload | 讓瀏覽器由安全功能變數名稱列表 (Preload List) 決定是否本地替換為 HTTPS 請求 |
最後這個 preload
可能有點抽象,就是各大瀏覽器廠商 (Chrome/Firefox/IE/Safari/Edge) 共同維護的一個功能變數名稱列表 (Preload List),你可以 在這裡查詢 ,chrome 瀏覽器可以直接在本地訪問 chrome://net-internals/#hsts
查詢。
設定 preload
參數,瀏覽器會 根據當前網站滿足的條件 嘗試把網站加入這個功能變數名稱列表 (Preload List),其他用戶再訪問這個網站的時候,如果這個網站功能變數名稱存在於這個功能變數名稱列表中,則自動啟用 HTTPS 訪問。
當用戶第一次訪問一個從來沒訪問過的網站時,本地是沒有 HSTS 信息的,所以這個第一次的會話仍然是可能被劫持的。preload
就是為瞭解決這個第一次會話劫持的問題的。
值得註意的是:一旦 HSTS 生效,在
max-age
指定的時間內,你再想把網站重定向為 HTTP,之前的老用戶會被無限重定向。而且一旦網站證書錯誤,用戶無法選擇忽略。
HSTS 是個大招,不要隨便開,不然技能冷卻時間的時間內。
結語
至此,《Said - 從 HTTP 到 HTTPS 》 系列已經完結。當今互聯網上多數站點都陸續部署上或者正在部署 HTTPS,主要是因為 HTTPS 的安全性,以及當前主流的瀏覽器支持的 HTTP/2.0 需要 HTTPS 為基礎。同時,百度也正在 積極推動 HTTPS的收錄,而 google 也聲明瞭 HTTPS 會提升一點點的網站排名,但變化不會很明顯。
最簡單直觀的一個情況,常見的流量劫持 —— 比如你的手機訪問某個網站,網頁中被某些不良的運營商劫持,強行插入了一些廣告:
web 發展迅猛,技術日新月異層出不窮。web 的安全性同樣是一場持久的攻防戰。而 HTTPS 的普及,為 web 通信構建了更加良好和安全的根基。儘快給你的網站也部上 HTTPS 吧,迎接更好的 web 時代。
這篇文章首發於我的個人網站:聽說 - https://tasaid.com/,建議在我的個人網站閱讀,擁有更好的閱讀體驗。
這篇文章與 博客園 和 Segmentfault 共用。
前端開發QQ群:377786580