我正在用Springboot和Springboot Security构建一个API,以及一个与此API交互的前端。我已经测试了Postman中工作正常的所有端点,但是当使用Axios向API发送POST请求时(在我的情况下,用于生成JWT的登录请求),我收到了一个401错误,这很奇怪,因为这个请求不需要任何授权。
当尝试解决这个问题时,大多数帖子只是错误地将Auth令牌传递到请求中的问题,但这里的情况并非如此,因为端点不需要auth令牌(请参阅成功的 Postman 请求)。我发现其他类似的帖子指出这可能是一个与cors相关的问题,但是在调整控制器以包含相关的@CrossOrigin
注解,并在从filterChain
中排除.cors()
时测试结果后,这个问题仍然存在,我几乎没有利用它来进行故障排除。
SecurityFilterChain
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
private AuthEntryPointJwt authorizationHandler;
@Autowired
UserDetailsServiceImpl userDetailsService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(authorizationHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.antMatchers("/api/v1/reviews/**").permitAll()
.antMatchers("/api/v1/test/**").permitAll().anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); }
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
控制器
@CrossOrigin(origins = "http://localhost:5173", maxAge = 3600)
@RestController
@RequestMapping("/api/v1/auth")
public class AuthController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserRepository userRepository;
@Autowired
PasswordEncoder encoder;
@Autowired
JwtUtils jwtUtils;
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getId(), userDetails.getUsername(), userDetails.getEmail()));
}
auth.service.js
import axios from "axios";
const API_URL = "http://localhost:8080/api/v1/auth/";
export default class AuthService {
login(username, password) {
console.log(API_URL + "signin");
console.log(username, password);
return axios
.post(API_URL + "signin", { username, password })
.then((response) => {
if (response.data.accessToken) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
});
}
logout() {
localStorage.removeItem("user");
}
register(username, email, password) {
return axios.post(API_URL + "signup", {
username,
email,
password,
});
}
}
Postman请求成功
Axios请求失败
请求头(来自网络页签)
// GENERAL
Request URL: http://localhost:8080/api/v1/auth/signin
Request Method: POST
Status Code: 401
Remote Address: [::1]:8080
Referrer Policy: strict-origin-when-cross-origin
// RESPONSE HEADERS
HTTP/1.1 401
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:5173
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Tue, 27 Jun 2023 20:38:38 GMT
Keep-Alive: timeout=60
Connection: keep-alive
// REQUEST HEADERS
POST /api/v1/auth/signin HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 49
Content-Type: application/json
Host: localhost:8080
Origin: http://localhost:5173
Referer: http://localhost:5173/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
我已经尝试包括尽可能多的信息,但如果有什么我可以提供,我错过了,这将有助于解决问题,让我知道。
1条答案
按热度按时间7gyucuyw1#
您应该在POST请求的主体中传递JSON对象: