首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular 4无法在报头中设置CSRF-TOKEN

Angular 4无法在报头中设置CSRF-TOKEN
EN

Stack Overflow用户
提问于 2017-08-19 06:51:03
回答 3查看 6.5K关注 0票数 0

我有一个Spring boot RESTful服务,其中的Spring security配置如下:

代码语言:javascript
复制
protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.cors().and()
                /*.formLogin().loginPage("/auth")
                .permitAll().and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and().httpBasic().and()*/
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
    }

&

代码语言:javascript
复制
public class CsrfHeaderFilter extends OncePerRequestFilter {

private static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
    if (csrf != null) {
        response.addHeader("X-CSRF-TOKEN", csrf.getToken());
        Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME);
        String token = csrf.getToken();

        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
            cookie = new Cookie(CSRF_COOKIE_NAME, token);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
    }

    filterChain.doFilter(request, response);
}

}

我正在使用Angular 4(最新版本)调用RESTful服务。它正在做一个post请求,抱怨并抛出一个403禁止的“无法验证提供的CSRF令牌,因为您的会话没有找到”。这是预期的,因为在发送post请求时,X-CSRF-TOKEN标头没有设置,但此标头确实存在:- Set-Cookie:XSRF-TOKEN=;Path=/

角度:

auth.service.ts:

代码语言:javascript
复制
const body = 'SOMERANDOMKEY1111';

const headers = new HttpHeaders().set('Content-Type', 'application/json').set('withCredentials', 'true');

    return this._http.post(this.endpoint + this.auth, body, {
      headers: headers
    });

app.module.ts (注意: post请求使用HttpClient ):

代码语言:javascript
复制
providers: [ ...
{
    provide: XSRFStrategy, useFactory: xsrfFactory
}...]
export function xsrfFactory() {
  return new CookieXSRFStrategy('XSRF-TOKEN', 'XSRF-TOKEN');
}

我关注了this并阅读了文档,但似乎无法使其正常工作。

EN

回答 3

Stack Overflow用户

发布于 2018-07-31 18:00:41

当我开始使用Spring和angular5时,我也遇到了同样的问题:

问:如何在angular发出的每个请求上设置X-CSRF令牌?

Sol :服务器端:

  • 首先您需要在服务器端配置csrf安全
  • 在服务器端您需要编写一个api在浏览器上设置cookie(cookie中的X- csrf令牌),此api在没有任何安全性的情况下命中(在此api上禁用csrf,假定接口名称为/info)

注意: /info这个接口只在第一次加载angular应用时调用一次(需要在angular应用加载的第一个页面中添加)

角度边:

  • 当应用程序加载到angular的第一个页面/组件时,在oninit内,您需要调用此路由"/info“(您需要在angular中创建服务并在那里调用此接口)。我在布局/导航栏组件上设置了此设置,因为当应用程序加载时,此组件首先加载
  • ,然后在app.module.ts内部,我们需要导入

从‘@

/common/http’导入{ HttpClientModule };

并将此模块添加到imports数组中,如下所示:

代码语言:javascript
复制
@NgModule({   imports: [
                     HttpClientXsrfModule.withOptions({
                     cookieName: 'XSRF-TOKEN',
                     headerName: 'X-XSRF-TOKEN',
         })]

在-then服务中,您需要按如下方式更改请求: user.service.ts

代码语言:javascript
复制
 registeruser(data) {
    console.log(data)
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers, withCredentials: true });
    return this.http.post(this.url + '/avssymbuaa/api/register', data, options).map(res => res.json());
  }

  • 注意事项:您需要在服务

上导入此文件

从‘@

/http’导入{ Http,Headers,RequestOptions,Response,URLSearchParams };

也许这对你有帮助,谢谢

票数 2
EN

Stack Overflow用户

发布于 2017-08-28 01:07:22

该响应是被禁止的,因为spring服务器或您的代理被期望接收报头中的X-CSRF令牌,而您没有发送它。

1.请确保您正在执行POST (on LOG )方法来接收CSRF-TOKEN

2.将收到的令牌存储在cookie或本地存储中

3.创建post并将token添加到头部,如下所示:

代码语言:javascript
复制
let headers = new Headers({ 'XSRF-TOKEN', 'the token received after login' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url,body,options);
票数 0
EN

Stack Overflow用户

发布于 2018-03-15 03:51:57

如果您的Angular UI和RESTful服务位于不同的域名,则您的Angular代码无法读取您的后台设置的cookie。要在本地工作区中解决这个问题,您可以使用set up cli proxy,但是对于生产环境,如果您使用的是Apache HTTP服务器,则需要设置反向代理。下面是一个示例:

对于https

代码语言:javascript
复制
<VirtualHost *:443>
    ServerName localhost
    SSLEngine on
    SSLProxyEngine On
    SSLCertificateFile conf/ssl/newfile.crt
    SSLCertificateKeyFile conf/ssl/newfile.key
    ProxyPass /api/ https://yoursite/api/
    ProxyPassReverse /api/ https://yoursite/api/
</VirtualHost>

对于http

代码语言:javascript
复制
<VirtualHost *:80>
    ServerName localhost
    ProxyPass /api/ http://yoursite/api/
    ProxyPassReverse /api/ http://yoursite/api/
</VirtualHost>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45765990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档