csurf express.js和angular,由token标记的秘密

时间:2017-11-20 15:15:39

标签: angular express csrf

我正在使用express.js和angular进行项目。我尝试按照https://github.com/expressjs/csurf

上的自述文件中的说明实现csurf

当我通过csurf源代码进行调试时,我注意到加载角度视图时生成的secret在第二个请求中被token覆盖。因此secrettoken是平等的。我花了两天时间弄清楚为什么会发生这种情况以及我做错了什么。

也许你知道什么是错的,可以帮助我吗?

这是我的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();
  }
}

1 个答案:

答案 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。

这听起来不准确吗?