ForbiddenError: invalid csrf token nodejs and Angular Ionic app
ForbiddenError: invalid csrf token nodejs and Angular Ionic app
我正在使用 Ionic + Angular + NodeJs 应用程序来启用 CSRF 保护。有一段时间它工作正常,但突然停止工作并向我发送消息
ForbiddenError: invalid csrf token
我的代码很简单,几天以来我一直在努力寻找解决方法,但似乎所有尝试都失败了。
Node JS 服务器 运行 在端口 8089 上(例如)具有 CSRF 保护
// [This is only for test purpose]
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization");
next();
});
app.use(bodyParser.json({limit: '20mb'})); /* {limit: "20mb"} */
app.use(cookieParser());
const csrfProtection = csurf({
cookie: true,
ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],
});
// base url is /api --> e.g (localhost:8089/api)
// it didn't worked with / only
app.use(config.base_url, csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
// csrfProtection is not yet applied
app.use(config.base_url, csrfProtection, HelperRouter); //post route
Ionic 中的应用程序模块 + Angular
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
MenuComponentModule,
FontAwesomeIconsModule,
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN',
}),
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: HTTP_INTERCEPTORS, useClass: CSRFTokenInterceptor, multi: true }
],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
我也试过添加 HttpInterceptor // 这也没用
@Injectable({
providedIn: 'root'
})
export class CSRFTokenInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
const token = this.tokenExtractor.getToken() as string;
console.log(token);
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
还在 Ionic + Angular 应用程序中启用了代理
{
"/v0": {
"target": "http://localhost:8089/api/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
}
}
回应header
HTTP/1.1 403 Forbidden
x-powered-by: Express
access-control-allow-origin: *
server: nginx/1.19.0
date: Tue, 05 Jan 2021 11:38:10 GMT
content-type: text/html; charset=utf-8
content-length: 1018
connection: close
access-control-allow-methods: *
access-control-allow-headers: X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization
content-security-policy: default-src 'none'
x-content-type-options: nosniff
请求header
POST /v0/validateReferences HTTP/1.1
Host: localhost:4200
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: application/json, text/plain, */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 53
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/account/login
Cookie: _csrf=k5nvA7BbJQ9a2GvPdlpisfCQ
这是怎么回事
- 如果我禁用 CSRF 保护,该路由将起作用。
- 请求转到正确的路径。 /v0(来自代理)
- 前缀显示 CSRF 令牌。
我已将项目上传到 GitHub 以防有人试一试
Project link
CSRF实现终于解决了。完成的实现在 GitHub 项目中。 GitHub
一些改变帮助我完成了这些事情
首先我更改了 csrf get route root path
app.use('/', csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
然后我在 ionic angular app
中更改了代理配置文件
{
"/api/v0/*": {
"target": "http://localhost:8089/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
} }
然后我改变了我的服务来调用端点
/api/v0/validate // post route
我已经在 GitHub 项目中添加了所有内容,所以如果有人遇到 CSRF 问题,他们可以使用该项目。
我正在使用 Ionic + Angular + NodeJs 应用程序来启用 CSRF 保护。有一段时间它工作正常,但突然停止工作并向我发送消息
ForbiddenError: invalid csrf token
我的代码很简单,几天以来我一直在努力寻找解决方法,但似乎所有尝试都失败了。
Node JS 服务器 运行 在端口 8089 上(例如)具有 CSRF 保护
// [This is only for test purpose]
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization");
next();
});
app.use(bodyParser.json({limit: '20mb'})); /* {limit: "20mb"} */
app.use(cookieParser());
const csrfProtection = csurf({
cookie: true,
ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],
});
// base url is /api --> e.g (localhost:8089/api)
// it didn't worked with / only
app.use(config.base_url, csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
// csrfProtection is not yet applied
app.use(config.base_url, csrfProtection, HelperRouter); //post route
Ionic 中的应用程序模块 + Angular
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
MenuComponentModule,
FontAwesomeIconsModule,
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN',
}),
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: HTTP_INTERCEPTORS, useClass: CSRFTokenInterceptor, multi: true }
],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
我也试过添加 HttpInterceptor // 这也没用
@Injectable({
providedIn: 'root'
})
export class CSRFTokenInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
const token = this.tokenExtractor.getToken() as string;
console.log(token);
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
还在 Ionic + Angular 应用程序中启用了代理
{
"/v0": {
"target": "http://localhost:8089/api/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
}
}
回应header
HTTP/1.1 403 Forbidden
x-powered-by: Express
access-control-allow-origin: *
server: nginx/1.19.0
date: Tue, 05 Jan 2021 11:38:10 GMT
content-type: text/html; charset=utf-8
content-length: 1018
connection: close
access-control-allow-methods: *
access-control-allow-headers: X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization
content-security-policy: default-src 'none'
x-content-type-options: nosniff
请求header
POST /v0/validateReferences HTTP/1.1
Host: localhost:4200
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: application/json, text/plain, */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 53
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/account/login
Cookie: _csrf=k5nvA7BbJQ9a2GvPdlpisfCQ
这是怎么回事
- 如果我禁用 CSRF 保护,该路由将起作用。
- 请求转到正确的路径。 /v0(来自代理)
- 前缀显示 CSRF 令牌。
我已将项目上传到 GitHub 以防有人试一试 Project link
CSRF实现终于解决了。完成的实现在 GitHub 项目中。 GitHub
一些改变帮助我完成了这些事情 首先我更改了 csrf get route root path
app.use('/', csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
然后我在 ionic angular app
中更改了代理配置文件{
"/api/v0/*": {
"target": "http://localhost:8089/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
} }
然后我改变了我的服务来调用端点
/api/v0/validate // post route
我已经在 GitHub 项目中添加了所有内容,所以如果有人遇到 CSRF 问题,他们可以使用该项目。