angular4 httpclient csrf 不发送 x-xsrf-token [英] angular4 httpclient csrf does not send x-xsrf-token

查看:22
本文介绍了angular4 httpclient csrf 不发送 x-xsrf-token的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在angular文档中,提到angularhttpclient会自动发送X-XSRF-TOKEN<X-XSRF-TOKEN<中的cookieXSRF-TOKEN的值/code> 发布请求.文档链接

In angular documentation, it is mentioned that the angular httpclient will automatically send the value of cookie XSRF-TOKEN in the header X-XSRF-TOKEN of post request. Documentation link

但它不会为我发送标头.这是我的代码

But it does not send the header for me. Here is my code

用于设置 cookie 的 Nodejs 代码

router.get('/set-csrf',function(req,res,next){
    res.setHeader('Set-Cookie', "XSRF-TOKEN=abc;Path=/; HttpOnly; SameSite=Strict");    
    res.send();
  })

我在 app.module.ts 中使用了 httpclient

I have used the httpclient in app.module.ts

imports: [
  HttpClientModule
]

** 以上代码仅用于调试目的.我没有 set-csrf 端点.

** The above code is just for debug purpose. I do not have a set-csrf endpoint.

但是当我发送 post 请求时它不发送任何标头.我无法调试.

But it does not send any header when I send a post request. I am not able to debug.

我也在 angular 的 github 存储库中添加了这个问题.HttpXsrfInterceptor 检查请求是 GET 还是 HEAD,或者是否以 http 开头.如果为 true,则跳过添加标题.

I have added the issue in the github repository of angular too. HttpXsrfInterceptor checks if the request is GET or HEAD, or if it starts with http. If true, it skips adding the header.

这是InterceptorX 中的代码班级

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const lcUrl = req.url.toLowerCase();
    // Skip both non-mutating requests and absolute URLs.
    // Non-mutating requests don't require a token, and absolute URLs require special handling
    // anyway as the cookie set
    // on our origin is not the same as the token expected by another origin.
    if (req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') ||
        lcUrl.startsWith('https://')) {
      return next.handle(req);
    }
    const token = this.tokenService.getToken();

    // Be careful not to overwrite an existing header of the same name.
    if (token !== null && !req.headers.has(this.headerName)) {
      req = req.clone({headers: req.headers.set(this.headerName, token)});
    }
    return next.handle(req);
  }

我不知道为什么他们跳过了 http/s 部分.这是我的 github 中的问题

I am not sure why they have skipped for http/s part. Here is my issue in github

推荐答案

您正在寻找的是 HttpClientXsrfModule.

请在此处阅读更多相关信息:https://angular.io/api/common/http/HttpClientXsrfModule.

Please read more about it here: https://angular.io/api/common/http/HttpClientXsrfModule.

你的用法应该是这样的:

Your usage should be like this:

imports: [   
 HttpClientModule,  
 HttpClientXsrfModule.withOptions({
   cookieName: 'My-Xsrf-Cookie', // this is optional
   headerName: 'My-Xsrf-Header' // this is optional
 }) 
]

此外,如果您的代码通过绝对 URL 定位 API,默认 CSRF 拦截器将无法开箱即用.相反,您必须实现自己的拦截器,它不会忽略绝对路由.

Additionally, if your code targets API via absolute URL, default CSRF interceptor will not work out of the box. Instead you have to implement your own interceptor which does not ignore absolute routes.

@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {

  constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const headerName = 'X-XSRF-TOKEN';
    let token = this.tokenExtractor.getToken() as string;
    if (token !== null && !req.headers.has(headerName)) {
      req = req.clone({ headers: req.headers.set(headerName, token) });
    }
    return next.handle(req);
  }
}

最后将其添加到您的提供者:

And finally add it to your providers:

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, multi: true }
]

这篇关于angular4 httpclient csrf 不发送 x-xsrf-token的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆