大部分同窗應該都知道 HTTP 協議的網站是不安全的,存在中間人劫持的狀況,所以咱們日常開發的網頁都會將 HTTP 協議升級爲 HTTPS,以確保不會被中間人劫持。瀏覽器
注:本文不涉及 HTTPS 的實現原理以及中間人劫持的概念,不瞭解的同窗先去惡補
緩存
但是大家覺得這樣就絕對安全了嗎?咱們想一想下面的場景:安全
一般狀況下,咱們打開一個普通的網站多是經過如下幾個方式:bash
當採用 直接輸入域名 的方式時,以下圖所示: 服務器
這時候咱們並無告訴瀏覽器當前請求的網站協議是https,然而咱們最終打開的仍是 https 協議的百度網站。這是爲何呢?其實就是重定向幫咱們作了肉眼看不見的事情,具體流程見下圖app
那麼這個過程當中第一步就會涉及名文的傳輸,所以有了被中間人攻擊的機會,因此咱們該如何避免這種狀況的出現呢?答案就是本文須要介紹的 HSTSMDN 對 HSTS 的定義很是直白網站
HTTP Strict Transport Security
(一般簡稱爲HSTS)是一個安全功能,它告訴瀏覽器只能經過HTTPS訪問當前資源,而不是HTTP。搜索引擎
經過定義咱們能夠畫出下面這樣的流程圖spa
當發起 http 的請求,不通過服務器直接變成 HTTPS 將請求發出去。code
具體怎麼才能讓 HSTS 其做用呢?咱們接着看。
經過給https協議的網站的response header配置Strict-Transport-Security
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains(可選); preload(可選,非標準)
複製代碼
每一個屬性的定義以下:
咱們看到百度的網站也設置了Strict-Transport-Security。
表示在172800秒的時間內訪問百度的主頁都是以https的形式,不過他並無設置includeSubDomains這個屬性。
細心的同窗可能發現了,有一種狀況下仍是沒辦法避免中間人劫持。那就是,在用戶第一次訪問網站而且使用 http 協議的狀況下,若是真要全面防止只能經過給域名添加 preload 的方式。具體方法請參加 MDN 添加preload
有了上面的基礎,讓咱們總結一下三種首次訪問的狀況
沒有HSTS
有HSTS,沒有preload
有HSTS以及preload(最佳實踐)
最後咱們應該注意,在生產環境下使用 HSTS 應當特別謹慎,由於一旦瀏覽器接收到HSTS Header(假若有效期是1年),可是網站的證書又剛好出了問題,那麼用戶將在接下來的1年時間內都沒法訪問到該網站,直到證書錯誤被修復,或者用戶主動清除瀏覽器緩存。