我正在使用express.js和angular进行项目。我尝试按照https://github.com/expressjs/csurf
上的自述文件中的说明实现csurf当我通过csurf
源代码进行调试时,我注意到加载角度视图时生成的secret
在第二个请求中被token
覆盖。因此secret
和token
是平等的。我花了两天时间弄清楚为什么会发生这种情况以及我做错了什么。
也许你知道什么是错的,可以帮助我吗?
这是我的express.js配置
const express = require('express');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const csurf = require('csurf');
const app = express();
const csrfProtection = csurf({
cookie: {
key: 'XSRF-TOKEN',
path: '/'
}
});
// Parser
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended: false
}));
// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));
// API location
app.use('/api', csrfProtection, bodyParser.json(), api);
// Send all other requests to the Angular app
app.get('*', csrfProtection, (req, res) => {
const cookie = req.csrfToken();
console.log("COOKIE", cookie);
res.cookie('XSRF-TOKEN', cookie);
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
// Set port
const port = process.env.PORT || 3000;
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
和调用后端api的角度服务
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import { AppService } from '../../shared/services';
@Injectable()
export class LoginService {
constructor(private http: Http) { }
login(cred: any): Promise<Response> {
const HEADERS = new Headers();
const csrfCookie = AppService.getCookie('XSRF-TOKEN');
console.log(csrfCookie);
if (csrfCookie) {
HEADERS.append('csrf-token', csrfCookie);
}
console.log(HEADERS);
return this.http.post('/api/login', JSON.stringify(cred), { headers: HEADERS })
.map(res => res.json()).toPromise();
}
}
答案 0 :(得分:0)
@arthurr -
我没有彻底看过,但首先要突出的是你设置的地方:
// Send all other requests to the Angular app
app.get('*', csrfProtection, (req, res) => {
const cookie = req.csrfToken();
console.log("COOKIE", cookie);
res.cookie('XSRF-TOKEN', cookie);
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
如果错误,有人会纠正我,但req.csrfToken()方法正在从一个秘密生成一个令牌。您将此令牌嵌入要提交的表单中。然后将其与秘密进行比较(当您使用cookie模式时,将其作为cookie存储在客户端中,您将其命名为XSRF-TOKEN)。
乍看之下,您遇到的问题是您正在尝试发送csurf COOKIE(不应该通过请求发送的秘密),而不是正确地在标头中发送csurf TOKEN。
这听起来不准确吗?