為 Spring Cloud Gateway 設定 CORS 策略
1. 概述
跨來源資源共享 (CORS) 是一種基於瀏覽器的應用程式的安全機制,允許一個網域的網頁存取另一個網域的資源。瀏覽器實施同源存取策略來限制任何跨網域應用程式存取。
此外,Spring 還提供一流的支持,可在任何 Spring、Spring Boot Web 和 Spring Cloud 閘道應用程式中輕鬆設定 CORS。
在本文中,我們將學習如何使用後端 API 設定 Spring Cloud Gateway 應用程式。此外,我們將存取網關 API 並調試常見的 CORS 相關錯誤。
然後,我們將使用 Spring CORS 支援來配置 Spring gateway API。
2. 使用 Spring Cloud Gateway 實作 API 網關
假設我們需要建立一個 Spring Cloud 網關服務來公開後端 REST API。
2.1.實作後端 REST API
我們的後端應用程式將有一個端點來傳回User
資料。
首先,我們對User
類別進行建模:
public class User {
private long id;
private String name;
//standard getters and setters
}
接下來,我們將使用getUser
端點實作UserController
:
@GetMapping(path = "/user/{id}")
public User getUser(@PathVariable("id") long userId) {
LOGGER.info("Getting user details for user Id {}", userId);
return userMap.get(userId);
}
2.2.實現Spring Cloud網關服務
現在讓我們使用 Spring Cloud Gateway 支援來實作 API 網關服務。
首先,我們將包含spring-cloud-starter-gateway
依賴項:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>4.1.5</version
</dependency>
2.3.設定API路由
我們可以使用 Spring Cloud Gateway 路由選項來公開使用者服務端點。
我們將使用/user
路徑配置predicates
,並使用後端 URI http://<hostname>:<port>
設定uri
屬性:
spring:
cloud:
gateway:
routes:
- id: user_service_route
predicates:
- Path=/user/**
uri: http://localhost:8081
3. 測試 Spring Gateway API
現在我們將使用 cURL 命令和瀏覽器視窗從終端測試 Spring 網關服務。
3.1.使用 cURL 測試網關 API
讓我們運行用戶和網關這兩個服務:
$ java -jar ./spring-backend-service/target/spring-backend-service-1.0.0-SNAPSHOT.jar
$ java -jar ./spring-cloud-gateway-service/target/spring-cloud-gateway-service-1.0.0-SNAPSHOT.jar
現在,讓我們使用網關服務 URL 存取/user
端點:
$ curl -v 'http://localhost:8080/user/100001'
< HTTP/1.1 200 OK
< Content-Type: application/json
{"id":100001,"name":"User1"}
如上所述,我們能夠取得後端 API 回應。
3.2.使用瀏覽器控制台進行測試
為了在瀏覽器環境中進行實驗,我們將開啟前端應用程序,例如https://www.baeldung.com,
並使用瀏覽器支援的開發人員工具選項。
我們將使用 Javascript fetch
函數從不同的原始 URL 呼叫 API:
fetch("http://localhost:8080/user/100001")
從上面我們可以看到,由於CORS錯誤,API請求失敗。
我們將進一步從瀏覽器的網路標籤調試 API 請求:
OPTIONS /user/100001 HTTP/1.1
Access-Control-Request-Method: GET
Access-Control-Request-Private-Network: true
Connection: keep-alive
Host: localhost:8080
Origin: https://www.baeldung.com
另外,讓我們驗證 API 回應:
HTTP/1.1 403 Forbidden
...
content-length: 0
上述請求失敗,因為網頁 URL 的 schema ,
domain 和 port 與網關 API 的不同。瀏覽器期望伺服器包含Access-Control-Allow-Origin
標頭,但卻收到錯誤。
預設情況下,由於來源不同, Spring 在預檢OPTIONS
請求上傳回Forbidden
403
錯誤。
接下來,我們將使用 Spring Cloud 網關支援的 CORS 配置來修復該錯誤。
4. API網關中設定CORS策略
現在,我們將設定 CORS 策略以允許不同的來源存取網關 API。
讓我們使用globalcors
屬性來設定 CORS 存取策略:
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "https://www.baeldung.com"
allowedMethods:
- GET
allowedHeaders: "*"
我們應該注意到, globalcors
屬性會將 CORS 策略應用於所有路由端點.
或者,我們可以為每個 API 路由設定 CORS 策略:
spring:
cloud:
gateway:
routes:
- id: user_service_route
....
metadata:
cors:
allowedOrigins: 'https://www.baeldung.com,http://localhost:3000'
allowedMethods:
- GET
- POST
allowedHeaders: '*'
allowedOrigins
欄位可以配置為特定的域名,或逗號分隔的域名,或設定為*通配符以允許任何跨域。同樣, allowedMethods
和allowedHeaders
屬性可以配置為特定值或 * 通配符。
此外,我們可以使用替代的allowedOriginsPattern
配置來為跨來源模式匹配提供更大的靈活性:
allowedOriginPatterns:
- https://*.example1.com
- https://www.example2.com:[8080,8081]
- https://www.example3.com:[*]
與allowedOrigins
屬性相反, allowedOriginsPattern
允許在 URL 的任何部分中使用 * 通配符,包括用於模式匹配的方案、網域名稱和連接埠號碼。此外,我們可以在括號內指定以逗號分隔的連接埠號碼。但是, allowedOriginsPattern
屬性不支援任何正規表示式。
現在,讓我們在瀏覽器的控制台視窗中重新驗證使用者 API:
我們現在從 API 閘道收到 HTTP 200 回應。
另外,讓我們確認OPTIONS
API 回應中的Access-Control-Allow-Origin
標頭:
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://www.baeldung.com
Access-Control-Allow-Methods: GET
content-length: 0
我們應該注意,建議配置一組有限的允許來源以提供最高等級的安全性。
預設情況下,CORS 規範不允許在任何跨來源請求中使用任何 cookie 或 CSRF 令牌。但是,我們可以使用設定為 true 的allowedCredentials
屬性來啟用它。此外,當 allowedCredentials 與allowedOrigins and
allowedHeaders
屬性中的 * 通配符一起使用時, allowedCredentials
不起作用.
5. 結論
在本文中,我們學習如何使用 Spring Cloud 網關支援來實現網關服務。從瀏覽器控制台測試 API 時,我們也遇到了常見的 CORS 錯誤。
最後,我們示範如何透過使用allowedOrigins,
和allowedMethods
屬性設定應用程式來修復 CORS 錯誤。
與往常一樣,範例程式碼可以在 GitHub 上找到。