如何在 ajax POST 请求中设置标头以包含 CSRF 令牌

Posted

技术标签:

【中文标题】如何在 ajax POST 请求中设置标头以包含 CSRF 令牌【英文标题】:How set up headers in ajax POST request to include CSRF token 【发布时间】:2017-01-18 23:39:20 【问题描述】:

帮助设置标题以消除该错误消息:"Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'."

html

<meta name="_csrf" th:content="$_csrf.token"/>
<meta name="_csrf_header" th:content="$_csrf.headerName"/>

我的 JS 代码:

var recipe = getRecipe();

var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
console.log(token);
console.log(header);
console.log(recipe);

var headers = ;
// How set up header for include CSRF-Token

$.ajax(
    url: "/recipe",
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    headers: headers,
    data: JSON.stringify(recipe, null, "\t"),
    success: function(data) 
        console.log(data);
    ,
    error : getErrorMsg
);

我的控制器代码:

 @RequestMapping(value = "/recipe", method = RequestMethod.POST, produces = "application/json")
        @ResponseStatus(HttpStatus.OK)
        public @ResponseBody
        String addRecipe(@RequestBody String jsonString) 
            Recipe recipe = Recipe.fromJson(jsonString);
            recipe.setUser(getLoggedUser());
            if (recipe.getCategory() != null)
                recipe.setCategory(categoryService.findById(recipe.getCategory().getId()));

recipe.setFavoriteUsers(recipeService.findById(recipe.getId()).getFavoriteUsers());
            recipe.setPhoto(recipeService.findById(recipe.getId()).getPhoto());

            recipeService.save(recipe);
            return recipe.toJson();
        

和安全配置:

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests()
                .anyRequest().hasRole("USER")
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .successHandler(loginSuccessHandler())
                .failureHandler(loginFailureHandler())
                .and()
            .logout()
                .permitAll()
                .logoutSuccessUrl("/login")
                .and()
            .csrf();
    

如何确定 csrf 已启用? 以及如何设置我的 ajax 请求的标头? 任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

可以按照您的示例读取令牌:

var token = $("meta[name='_csrf']").attr("content");

然后您可以设置 jQuery 以在所有后续请求中将 CSRF 令牌作为请求标头发送(您不必再担心了):

$.ajaxSetup(
    beforeSend: function(xhr) 
        xhr.setRequestHeader('X-CSRF-TOKEN', token);
    
);

【讨论】:

以上是关于如何在 ajax POST 请求中设置标头以包含 CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章

在groovy post请求中设置标头

在 URL 中设置请求标头?

如何在http get请求中设置标头?

如何在 google ads api 中设置请求标头

如何在 Flask 中设置响应标头?

如何在 WPF 应用程序中 SOAP 客户端的“Set-Cookie”标头响应的新请求中设置“Cookie”标头