2016-11-28 8 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を使用しています。私が理解しているところでは、デフォルトでAngular2はHTTPサービスを使用しているときにCSRF/XSRFをCookieXSRFStrategyでサポートしているので、ノード/エクスプレス側で何かを設定するだけです。 webpack-dev-serverのAngular2アプリはlocalhost:3000で実行され、node/expressサーバーはlocalhost:3001で実行されています。私はCORSをサポートしています。

XSRF-TOKENという名前のクッキーをdevtoolsのlocalhost:3000に表示しています。

このエラーを修正する方法をお勧めしますか?

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

//cors-middleware.jsは私の問題は、私だけapp.post('/loginUser)ルートでミドルウェアとしてCSRF機能を含めたということでした。

すべてのルートでそれを組み込んだとき、モジュールはうまくいきました。
let csrf = csurf(); app.get('/*', csrf, (req, res) => { res.sendFile(app.get('indexHTMLPath')); });

関連する問題