这是我实际的@Configuration类:
package com.example.churchbillboard2.configs;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("PUT", "DELETE", "POST", "GET")
.allowedHeaders("CustomAuth", "Authorization", "header3", "Origin", "Access-Control-Allow-Origin", "Content-Type",
"Accept", "Origin, Accept", "X-Requested-With",
"Access-Control-Request-Method", "Access-Control-Request-Headers")
.exposedHeaders("CustomAuth", "Origin", "Content-Type", "Accept", "Authorization",
"Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}
这是我的 Spring Boot 目标控制器:
package com.example.churchbillboard2.controllers;
import org.springframework.web.bind.annotation.RestController;
import com.example.churchbillboard2.security.SessionToken;
import com.example.churchbillboard2.services.TimeManager;
import com.example.churchbillboard2.services.UserService;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
@RequestMapping("/")
public class Login {
private UserService userService;
private TimeManager timeManager;
private SessionTokenWrapper sessionTokenWrapper;
public Login(UserService userService, TimeManager timeManager, SessionTokenWrapper sessionTokenWrapper) {
this.userService = userService;
this.timeManager = timeManager;
this.sessionTokenWrapper = sessionTokenWrapper;
}
@PostMapping(value = "/login")
public SessionToken getMethodName(@RequestBody LoginDTO user, HttpSession session) {
SessionToken sessionToken = (userService.getUserByUserName(user) == null) ? new SessionToken("Invalid User")
: new SessionToken(null);
sessionTokenWrapper.setSessionToken(sessionToken.getSessionToken());
System.out.println("sessionTokenWrapper.getSessionToken()");
System.out.println(sessionTokenWrapper.getSessionToken());
return sessionToken;
}
@PostMapping("/months")
public AvailableMonthsWrapper getMethodName(@RequestHeader("CustomAuth") String headerValue,
HttpSession session) {
System.out.println("headerValue");
System.out.println(headerValue);
return (sessionTokenWrapper.validateToken(headerValue))
? new AvailableMonthsWrapper(timeManager.availableMonths())
: new AvailableMonthsWrapper("Not Valid Session");
}
@GetMapping(value = "/")
public String getHome() {
return "Hi From Home";
}
}
注意 PostMapping 有一个自定义标头“/months”。
现在我尝试使用从 React 上的两个自定义挂钩中获取,以保留 sessionTokenWrapper bean 的 SessionScope。
我的 React 客户端正在 3000 端口本地主机上运行。但我需要我的 SpringBoot 服务器能够处理来自任何地方的请求,无论源 IP、源端口是什么。
我的第一个 Hook 是这样的:
export const validateLogin = async (userName, password) => {
const url = 'http://localhost:5000/login';
const loginData = {
username: userName,
password: password,
};
const response = await fetch(url, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(loginData),
});
if (response.ok) {
return await response.text();
} else {
throw new Error(`Request failed with status ${response.status}`);
}
}
我的第二个钩子是(发送自定义标头的钩子):
export const fetchMonths = async (sessionToken) => {
console.log('token: ', sessionToken);
const url = 'http://localhost:5000/months';
const response = await fetch(url, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'CustomAuth': sessionToken,
},
});
if (response.ok) {
return await response.text();
} else {
throw new Error(`Request failed with status ${response.status}`);
}
};
我不断收到各种错误,从
开始“当包含凭据时,允许的来源不能设置为“”...*”
致现在的,也是我最痛苦的一个:
“从源“http://localhost:3000”获取“http://localhost:5000/login”的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:无“访问”请求的资源上存在“-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。”
我对 Spring Boot 还很陌生,这个 cors 配置很混乱。我究竟做错了什么?我需要什么才能让我的 Spring Boot 服务器与任何客户端进行自由通信,即使它发送自定义标头也是如此。 (这是因为我稍后也需要将其扩展到 Android 客户端)。
对于任何有同样问题的人。我刚刚将 .allowedOrigins 更改为 .allowedOriginPatterns
registry.addMapping("/**")
.allowedOriginPatterns("*") //here
.allowedMethods("PUT", "DELETE", "POST", "GET")
.allowedHeaders("CustomAuth", "Authorization", "header3", "Origin", "Access-Control-Allow-Origin", "Content-Type",
"Accept", "Origin, Accept", "X-Requested-With",
"Access-Control-Request-Method", "Access-Control-Request-Headers")
.exposedHeaders("CustomAuth", "Origin", "Content-Type", "Accept", "Authorization",
"Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true);