序言
跨域資源共享「CORS」就是在不同的域名、協議、埠直接請求資源。本文主要講述了什麼是跨域,什麼情況下會出現預檢請求,我司的跨域安全訪問
什麼是跨域
同源策略
出於安全的原因,在沒有被允許的情況下瀏覽器限制從不同源「origin」發起請求,也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。
什麼才能是同源
源:由協議+域名+埠組成,也就是說,這個三個要統一才同源
例:
- http://www.baidu.com && https://www.baidu.com 不同源 協議不同
- http://api.baidu.com && http://www.baidu.com 不同源 域名不同
- http://www.baidu.com:8081 && http://www.baidu.com:8080 不同源 埠不同
- www.baidu.com/index.html && www.baidu.com/404.html 同源
什麼情況下會出現預檢請求
預檢請求
跨域資源共享標準新增了一組HTTP首部欄位,允許伺服器宣告哪些源站通過瀏覽器有許可權訪問哪些資源。在某些會對伺服器資料產生作用「需要修改資料庫」的請求「主要是GET以外的請求」,瀏覽器會先傳送通過OPTIONS方法傳送預檢請求,從伺服器那邊得到返回是否允許跨域。伺服器也可以攜帶是否需要身份憑證通知瀏覽器。
也就是說:在你傳送請求的時候,瀏覽器會自己先傳送一個預檢請求。後臺只需要識別請求的方法「OPTIONS」,然後返回一些資訊。 如下圖:
這裡有兩個login/請求,第一個是瀏覽器主動發出的。它的Request Method方法為 OPTIONS,然後伺服器的返回資訊:- access-control-allow-headers:允許你攜帶頭的引數
- access-control-allow-methods:允許你傳送請求的方法
- access-control-allow-origin:允許你傳送請求的地址
這部分資訊通知了你修改自己的請求引數來符合伺服器的要求, 伺服器如何除了瀏覽器傳送的預檢請求,可以參照這個MDN Server-Side_Access_Control (CORS)。
簡單請求
在以下情況下傳送的請求不會觸發預檢請求
-
使用以下方法之一:「GET HEAD POST」
-
頭部欄位在這個集合之內:「Accept, Accept-Language, Content-Language, Content-Type (需要注意額外的限制), DPR, Downlink, Save-Data, Viewport-Width, Width」
-
Content-Type以下三種之一:「text/plain,multipart/form-data,application/x-www-form-urlencoded」
-
...
例子:我在傳送登入的時候,頭部欄位自定義了Authorization,這時候就觸發預檢請求
我司的訪問控制方式
JSON Web Token「JWT」
公司主要採用的就是JWT的跨域認證解決方案。JWT的意思就是:使用者傳送登入資訊「使用者名稱,密碼」給伺服器,伺服器認證後生成一個JSON物件,給使用者儲存,之後使用者請求資料都需要帶上JWT來傳送請求。
步驟
-
- 登入 傳送使用者名稱密碼給伺服器驗證返回JWT
-
- 前端通過LocalStorage儲存JWT
-
- 之後的請求帶上JWT
-
- 驗證過期或者失敗直接返回401退到登入頁面
不足之處
- JWT一旦簽發了,在到期之前始終有效,這樣別人可以使用你的JWT獲取資料
- JWT過期或失效的時候,使用者仍然需要通過失效的JWT請求才能知道JWT已經失效
擴充套件閱讀
如果前端沒有跟後端建立統一API設計規範,可以使用這個 RESTful api