Springboot處理跨域請求
Springboot中如何處理跨域請求
一.什麼是跨域?
我們知道Url的一般格式:協議 + 域名(子域名 + 主域名) + 埠號 + 資源地址
比如:
https://www.itquanmingxing.cn:8080/users 是由https + www + itquanmingxing.cn + 8080 + users組成。
只要協議,子域名,主域名,埠號這四項組成部分中有一項不同,就可以認為是不同的域,不同的域之間互相訪問資源,就被稱之為跨域。
而我們的瀏覽器預設是不允許跨域請求的,因為它們都使用了同源策略,同源策略是由 Netscape 提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現在所有支援 JavaScript 的瀏覽器都會使用這個策略。
但是我們在實際開發中,由於各種原因又經常有跨域的需求,比如:現在的前端開發中都是前後端分離的開發模式,資料的獲取並非同源;或者A網站是電子商務管理訂單,B網站是進銷存抓取訂單資訊後做發貨;再比如做單點登入,在A網站登入後,跳轉到B網站時不需要再輸入使用者名稱密碼等。
所以我們怎麼解決這個跨域訪問的問題呢?
二 什麼是CORS
解決跨域請求,主要有JSONP,iframe,window.name,CORS等方式。其中CORS方式是最常用的跨域實現方式,而且是對各種請求方法、各種資料請求型別都是完美支援的。
跨域資源共享(CORS,Cross-origin resource sharing) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓執行在一個 origin (domain) 上的Web應用被准許訪問來自不同源伺服器上的指定的資源。當一個資源從與該資源本身所在的伺服器不同的域、協議或埠請求一個資源時,資源會發起一個跨域 HTTP 請求。
原理:在伺服器端設定允許跨域的請求頭,從而實現跨域,伺服器設定後前端通過正常的ajax請求即可。
三 Springboot中CORS的使用
CORS從具體的程式碼實現上來說比較方便,前端幾乎不需要寫任何程式碼就可以支援。主要是靠服務端進行配置。
CORS需要瀏覽器和伺服器同時支援。目前所有瀏覽器都支援該功能,IE瀏覽器不能低於IE10。
整個CORS通訊過程,都是瀏覽器自動完成,不需要使用者參與。對於開發者來說,CORS通訊與同源的AJAX通訊沒有差別,程式碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動新增一些附加的頭資訊,有時還會多出一次附加的請求,但使用者不會有感覺。
因此,實現CORS通訊的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨域通訊。
3.1 建立兩個springboot專案
為了方便,建立一個空的project,然後在空的project中建立兩個module代表兩個不同源的專案。
先建立空的工程:
再建立兩個module:
一個取名為provider(被訪問的專案),新增web依賴,一個取名為consumer(發起訪問的專案),新增web和thymeleaf依賴。
…
創建出來的專案結果如下:
3.2 新增測試程式碼
在provider專案中新增:
控制層方法:
在consumer專案中新增:
控制層方法和檢視頁中的ajax請求
修改consumer訪問埠為8080:
3.3 啟動專案測試
分別啟動這兩個專案
會發現由於同源策略的限制,請求無法傳送成功。
3.4 使用CORS
好,那我們現在就使用 CORS 在前端程式碼不做任何修改的情況下,實現跨域。
在provider專案提供的方法上新增
@CrossOrigin(value = "http://localhost:8088")
重新啟動專案訪問:發現可以成功訪問了。
按F12檢視請求頭資訊,發現多了一個允許訪問的域。
3.5 全域性配置CORS
這個註解可以用在方法上,也可以用在Controller上,但如果每一個方法上都去加註解包括說每個Controller上都去加註解都很麻煩,我們可以通過全域性配置一次性解決這個問題。
全域性配置只需要在 SpringMVC 的配置類中重寫 addCorsMappings 方法即可,方法上就不用加了,程式碼如下:
package com.example.provider.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class ProviderMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 專案中的所有介面都支援跨域
.allowedOrigins("http://localhost:8088") //允許哪些域能訪問我們的跨域資源
.allowedMethods("*")//允許的訪問方法"POST", "GET", "PUT", "OPTIONS", "DELETE"等
.allowedHeaders("*");//允許所有的請求header訪問,可以自定義設定任意請求頭資訊
}
}
這裡我們的ProviderMvcConfig配置類實現了WebMvcConfigurer介面並且重寫了addCorsMappings方法,我們來簡單介紹下我們的配置資訊
addMapping:配置可以被跨域的路徑,可以任意配置,可以具體到直接請求路徑。
allowedOrigins:允許哪些域名可以訪問我們的跨域資源,可以固定單條或者多條內容。
如:allowedOrigins("http://www.baidu.com")只有百度可以訪問我們的跨域資源。
allowedOrigins("*")代表允許任意路徑
allowedMethods:設定允許的請求方法型別訪問該跨域資源伺服器,如:POST、GET、PUT、OPTIONS、DELETE等。
allowedHeaders:允許所有的請求header訪問,可以自定義設定任意請求頭資訊,如:"X-YYYY-TOKEN"
allowCredentials: 是否允許請求帶有驗證資訊,使用者是否可以傳送、處理 cookie
maxAge(3600) 設定允許訪問的時間
3.5 安全隱患。
置任意請求頭資訊,如:“X-YYYY-TOKEN”
allowCredentials: 是否允許請求帶有驗證資訊,使用者是否可以傳送、處理 cookie
maxAge(3600) 設定允許訪問的時間
``
3.5 安全隱患。
CORS 的工作過程是通過 Ajax 傳送跨域請求,這個也有潛在的威脅存在,常見的就是 CSRF(Cross-site request forgery)跨站請求偽造。跨站請求偽造也被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF,是一種挾制使用者在當前已登入的 Web 應用程式上執行非本意的操作的攻擊方法 。關於 CSRF 攻擊的具體介紹和防禦辦法,我們在學習SpringSecurity(spring安全框架)後再具體講解。