gpt4 book ai didi

java - 使用 Spring Boot(VueJS 和 Axios 前端)获取 Post 403 Forbidden

转载 作者:搜寻专家 更新时间:2023-10-30 22:09:57 26 4
gpt4 key购买 nike

我一直遇到 CORS 问题,我已经尝试了在 Stack Overflow 上可以找到的一切,基本上是在 Google 上找到的所有东西,但都没有成功。

所以我在后端有用户身份验证,在前端有一个登录页面。我用 Axios 连接了登录页面,这样我就可以发出发布请求并尝试登录,但我一直收到“预检请求”之类的错误,所以我修复了这个问题,然后我开始收到“Post 403 Forbidden”错误。

它看起来像这样:

POST http://localhost:8080/api/v1/login/ 403 (Forbidden)

即使尝试使用 Postman 登录也不起作用,所以显然有问题。将在下面发布类文件

在我的后端,我有一个名为 WebSecurityConfig 的类,它处理所有 CORS 的东西:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS");
}
};
}

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); // TODO: lock down before deploying
config.addAllowedHeader("*");
config.addExposedHeader(HttpHeaders.AUTHORIZATION);
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}


@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
http
.cors()
.and()
.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/h2/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/v1/login").permitAll()
.anyRequest().authenticated()
.and()
// We filter the api/login requests
.addFilterBefore(new JWTLoginFilter("/api/v1/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class);
// And filter other requests to check the presence of JWT in header
//.addFilterBefore(new JWTAuthenticationFilter(),
// UsernamePasswordAuthenticationFilter.class);
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Create a default account
auth.userDetailsService(userDetailsService);
// auth.inMemoryAuthentication()
// .withUser("admin")
// .password("password")
// .roles("ADMIN");
}
}

在我们用 VueJS 编写并使用 Axios 进行调用的前端

<script>
import { mapActions } from 'vuex';
import { required, username, minLength } from 'vuelidate/lib/validators';

export default {
data() {
return {
form: {
username: '',
password: ''
},
e1: true,
response: ''
}
},
validations: {
form: {
username: {
required
},
password: {
required
}
}
},
methods: {
...mapActions({
setToken: 'setToken',
setUser: 'setUser'
}),
login() {
this.response = '';
let req = {
"username": this.form.username,
"password": this.form.password
};

this.$http.post('/api/v1/login/', req)
.then(response => {
if (response.status === 200) {
this.setToken(response.data.token);
this.setUser(response.data.user);

this.$router.push('/dashboard');
} else {
this.response = response.data.error.message;
}
}, error => {
console.log(error);
this.response = 'Unable to connect to server.';
});
}
}
}
</script>

因此,当我通过 Chrome 的工具(网络)进行调试时,我注意到 OPTIONS 请求如下所示:

OPTIONS request going through

这是 POST 错误的图片:

POST Request Error

这是另一个处理 OPTIONS 请求的类(WebSecurityConfig 中引用的 JWTLoginFilter):

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);

}

@Override
public Authentication attemptAuthentication(
HttpServletRequest req, HttpServletResponse res)
throws AuthenticationException, IOException, ServletException {
AccountCredentials creds = new ObjectMapper()
.readValue(req.getInputStream(), AccountCredentials.class);
if (CorsUtils.isPreFlightRequest(req)) {
res.setStatus(HttpServletResponse.SC_OK);
return null;

}
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
Collections.emptyList()

)
);
}

@Override
protected void successfulAuthentication(
HttpServletRequest req,
HttpServletResponse res, FilterChain chain,
Authentication auth) throws IOException, ServletException {
TokenAuthenticationService
.addAuthentication(res, auth.getName());
}
}

最佳答案

配置axios的时候,可以简单的指定header一劳永逸:

import axios from "axios";

const CSRF_TOKEN = document.cookie.match(new RegExp(`XSRF-TOKEN=([^;]+)`))[1];
const instance = axios.create({
headers: { "X-XSRF-TOKEN": CSRF_TOKEN }
});
export const AXIOS = instance;

然后(这里我假设你使用的是 SpringBoot 2.0.0,虽然它应该也适用于 SpringBoot 1.4.x 以上版本)在你的 Spring Boot 应用程序中你应该添加以下安全配置。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
// CSRF Token
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// you can chain other configs here
}

}

这样,Spring 将在响应中将 token 作为 cookie 返回(我假设您先执行 GET),您将在 AXIOS 配置文件中读取它。

关于java - 使用 Spring Boot(VueJS 和 Axios 前端)获取 Post 403 Forbidden,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46009469/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com