2016-11-28 181 views
2

我使用node 6.5.0npm 3.10.3无效CSRF令牌错误(express.js)

我收到的时候我试图登录的用户在网站上的这个invalid csrf token错误。

{ ForbiddenError: invalid csrf token at csrf (/Users/Documents/web-new/node_modules/csurf/index.js:113:19)

在redis的存储会话的登录作品,未经csurf模块(https://github.com/expressjs/csurf)。使用csurf模块时,会话ID将存储在redis中,但我无法将正确的响应返回给客户端以登录用户。我正在使用Angular2和node/express。据我所知,在使用HTTP服务时,Angular2默认支持CSRX/XSRF和CookieXSRFStrategy,所以我只需要在node/express端配置一些东西。带有webpack-dev-server的Angular2应用程序在localhost:3000上运行,而节点/快递服务器在localhost:3001上运行。我支持CORS。

我能看到的名字XSRF-TOKEN饼干在devtools在localhost:3000

你能好心建议我怎么可能会修复这个错误?

//cors-middleware.js

var corsOptions = { 
    origin: 'http://localhost:3000', 
    credentials:true 
} 

app.use(cors(corsOptions)); 
app.use(function(req, res, next) { 
    res.setHeader('Content-Type','application/json'); 
     next(); 
    }) 
}; 

//index.js

import path from 'path'; 
import session from 'express-session'; 
import connectRedis from 'connect-redis'; 
import rp from 'request-promise'; 
import * as _ from 'lodash'; 
import cors from 'cors'; 
import csurf from 'csurf'; 

const redisStore = connectRedis(session); 
const dbStore = new redisStore(db); 

let baseUrl = app.getValue('baseUrl'); 

/* ~~ api authentication ~~ */ 

let options = { 
    method: 'POST', 
    url: `${baseUrl}/authenticate`, 
    rejectUnauthorized: false, 
    qs: { 
    username: 'someUsername', key: 'someKey' 
    }, 
    json: true 
}; 
rp(options) 
    .then(response => { 
     let apiToken = response.response; 
     app.setValue("token", apiToken); 
    }) 
    .catch(err => { 
     console.error(err); 
    }); 

/* ~~ configure session ~~ */ 

app.use(session({ 
    secret: app.getValue('env').SESSION_SECRET, 
    store: dbStore, 
    saveUninitialized: false, 
    resave: false, 
    rolling: true, 
    cookie: { 
     maxAge: 1000 * 60 * 30 // in milliseconds; 30 min 
    } 
})); 

/* ~~ login user ~~ */ 

let csrf = csurf(); 

app.post('/loginUser', csrf, (req, res, next) => { 
    let user = {}; 
    let loginOptions = { 
     method: 'POST', 
     url: `${baseUrl}/client/login`, 
     rejectUnauthorized: false, 
     qs: { 
      token: app.getValue('token'), 
      email: req.body.email, 
      password: req.body.password 
     }, 
     headers: { 
      'Content-Type': 'application/json' 
     }, 
     json: true 
    }; 

    rp(loginOptions) 
     .then(response => { 
      let userToken = response.response.token; 
      let clientId = response.response.clientId; 

      req.session.key = req.session.id; 

      user.userToken = userToken; 
      user.clientId = clientId; 


      let clientAttributeOptions = { 
       url: `${baseUrl}/client/${clientId}/namevalue`, 
       rejectUnauthorized: false, 
       qs: { 
        token: app.getValue('token'), 
        usertoken: userToken 
       }, 
       json: true 
      }; 

      return rp(clientAttributeOptions); 
     }) 
     .then(response => { 
      req.session.user = user; 
       res.send({user:user}) 
     }) 
     .catch(err => { 
      next(err); 
     }) 

}); 

回答

0

我的问题是,我是包括CSRF功能只在app.post('/loginUser)路线中间件。

当我把它所有的航线,模块正常工作。
let csrf = csurf(); app.get('/*', csrf, (req, res) => { res.sendFile(app.get('indexHTMLPath')); });