2016-11-28 5 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)

레디 스에서 세션을 저장와 로그인은 csurf 모듈 (https://github.com/expressjs/csurf)없이 작동한다. csurf 모듈을 사용하면 세션 ID가 redis에 저장되지만 사용자에게 로그인하기 위해 클라이언트에 적절한 응답을 반환 할 수 없습니다. 노드/익스프레스에서 Angular2를 사용하고 있습니다. 내가 이해하는 바로는 Angular2는 기본적으로 HTTP 서비스를 사용할 때 CSRF/XSRF를 CookieXSRFStrategy로 지원하므로 노드/익스프레스 쪽에서 구성해야합니다. 노드/익스프레스 서버가 localhost:3001에서 실행되는 동안 webpack-dev-server가있는 Angular2 앱은 localhost:3000에서 실행됩니다. 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

내 문제는 내가 단지 app.post('/loginUser) 경로에서 미들웨어로 CSRF 기능을 포함한 것을이었다을 //cors-middleware.js.

모든 경로에 포함 시켰을 때 모듈이 정상적으로 작동했습니다.
let csrf = csurf(); app.get('/*', csrf, (req, res) => { res.sendFile(app.get('indexHTMLPath')); });