首页 > 解决方案 > 如何在带有 Spring Boot 后端的 Vue.js 应用程序中包含 CSRF 令牌?

问题描述

我正在尝试使用浏览器的 Fetch API 向我的后端 REST API 发出 POST 请求,如下所示:

   submitRegistration() {
         const formElement = document.getElementById('register-form');
         fetch('http://localhost:8080/register', {
             method: 'POST',
             body: new FormData(formElement),
         });
     }

我正在从这个表格中获取数据:

<v-form id="register-form" @submit.prevent="submitRegistration" class="text-center" ref="form" v-model="valid" lazy-validation>
    <v-text-field type="text" name="username" v-model="form.username" :counter="25" :rules="usernameRules" label="Username" required></v-text-field>
    <v-text-field type="password" name="userPassword" v-model="form.password" :counter="25" :rules="passwordRules" label="Password" required></v-text-field>
    <v-text-field type="text" name="userEmail" v-model="form.email" :rules="emailRules" label="E-mail" required></v-text-field>
    <v-btn type="submit" text class="primary">Register</v-btn>
</v-form>

但是,作为响应,我的后端服务器收到403 Forbidden。问题是 CSRF 令牌,但我不知道如何生成它以将其包含在对后端 API 的 POST 请求中。

编辑:在 Spring Boot 中,我的 CORS 映射配置如下:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("http://localhost:9000").allowCredentials(true);
        }
    };
}

我发布这个是因为Response返回的对象给了我一个 403 状态并且是“cors”类型,即使如果我使用 HttpSecurity 完全禁用 CSRF,错误就会得到解决 -http.csrf().disable();

标签: javaspringspring-bootvue.jsvuetify.js

解决方案


这可以通过GET首先调用服务器来解决,然后按照此处的解决方案进行以下添加/更正:

  1. submitRegistration()方法中,在顶部添加以下内容:

        // Do a fetch to GET the XSRF-TOKEN as a cookie
        fetch('http://localhost:8080/register');
        const csrfToken = this.getCookie('XSRF-TOKEN');
        const headers = new Headers({
            'X-XSRF-TOKEN': csrfToken
        });
    
  2. 我们的 POST 请求现在看起来像这样:

       fetch('http://localhost:8080/register', {
            method: 'POST',
            headers,
            credentials: 'include',
            body: new FormData(formElement),
        })
    
  3. 在后端,我们需要将以下内容添加到我们的覆盖configure()方法中:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
    

    这告诉服务器将 CSRF 令牌作为名为 "XSRF-TOKEN" 的 cookie 发回,并从名为"X-XSRF-TOKEN"的标头中读取 CSRF 令牌。


推荐阅读