2016-09-19 33 views
0

我是一個試圖通過遵循一些教程和示例來啓動並運行的節點初學者。我想構建一個允許本地,Facebook,Twitter和谷歌登錄的JSON API,因此我使用passport.js。目前我試圖合併https://github.com/vitaly-t/pg-promise-demohttp://blog.slatepeak.com/refactoring-a-basic-authenticated-api-with-node-express-and-mongo/(對不起,代碼是這樣的一堆樣式不匹配),並且遇到我的日誌POST返回的問題:無法在提供正確憑據時發佈/ auth/login/local,它工作正常,如果我的憑據不好,我真的不明白爲什麼行爲會有所不同,除非護照本地正在做一些我沒有考慮的背景。我認爲相關的文件包括:Node Express pg-promise Passport-local JWT不能發佈

SERVER.js

'use strict'; 

var db = require('./db/db.js').db 
    , express = require('express') 
    , auth = require('./routes/auth') 
    , router = express.Router() 
    , app = express() 
    , routes = require('./routes/routes.js') 
    , bodyParser = require('body-parser') //must be before passport 
    , config = require('./conf/main'); 

app.use(bodyParser.urlencoded({ extended: true })); 
app.use(bodyParser.json()); 
app.use('/auth', auth); 

// Enable CORS from client-side - Will I need this? 
app.use(function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Access-Control-Allow-Credentials"); 
    res.header("Access-Control-Allow-Credentials", "true"); 
    next(); 
}); 

////////////////////////////////////////////// 
// Users Web API 
////////////////////////////////////////////// 
app.post('/users/local', routes.userAddLocal); 
app.get('/users', routes.getAllUsers); //This should go into the Admin App. Will they both be able to use Postgres at once? 


app.listen(config.port,() => { 
    console.log('\nReady for requests on http://localhost:' + config.port); 
}); 

AUTH.js

'use strict'; 
///////////////////////// Passport Setup 

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy 
    , JwtStrategy = require('passport-jwt').Strategy 
    , ExtractJwt = require('passport-jwt').ExtractJwt 
    , jwt = require('jsonwebtoken') 
    , db = require('../db/db.js').db 
    , config = require('../conf/main') 
    , express = require('express') 
    , bodyParser = require('body-parser') //must be before passport 
    , bcrypt = require('bcrypt-nodejs'); 

const jwtOptions = { 
    // Telling Passport to check authorization headers for JWT 
    jwtFromRequest: ExtractJwt.fromAuthHeader(), 
    // Telling Passport where to find the secret 
    secretOrKey: config.secret 
}; 

passport.use('local', new LocalStrategy({ 
    usernameField: 'email' 
    , passReqToCallback: false 
    , session: false //Turn off sessions, this is a stateless REST service using JWT 
    }, 
    function(username, password, done) { 
    db.users.findByEmail(username) 
     .then(function (user){ 
      if (!user) { return done(null, false); } 
      var pwMatch = bcrypt.compareSync(password, user.password); 
      if (!pwMatch) { return done(null, false); } 
      return done(null, user); 
     }) 
     .catch(function(error){ 
      return done(error); 
     }) 
    } 
)); 

passport.use('jwt', new JwtStrategy(jwtOptions, function(payload, done) { 
    console.log("jwt strategy top line"); 
    db.users.findById(payload._id) //maybe need payload.doc._id or payload.document._id 
     .then(function (user){ 
      if (user) { 
       done(null, user); 
      } else { 
       done(null, false); 
      } 
     }) 
     .catch(function(error){ 
      return done(err, false); 
     }) 
})); 

function generateToken(user) { 
    return jwt.sign(user, config.secret, { 
    expiresIn: 10080 // in seconds 
    }); 
}; 

var authRoutes = express.Router(); 
authRoutes.use(bodyParser.urlencoded({ extended: true })); 
authRoutes.use(bodyParser.json()); 
authRoutes.use(passport.initialize()); 

authRoutes.post('/login/local', passport.authenticate('local', { 
    function(req, res) { 
     var tokenObj = auth.generateToken({email: req.body.email, displayName: req.body.DisplayName}); 
     res.status(201).json({ 
      token: 'JWT ' + tokenObj, 
      user: req.body.displayName 
     }); 
    }, 
     failureRedirect: '/auth/notauth', 
     session: false 
    })); 

authRoutes.get('/notauth', function (req, res){ 
    res.status(401).send("Login Failed"); 
}); 

module.exports = authRoutes; 
module.exports.generateToken = generateToken; 

任何幫助,任何人都可以提供將不勝感激。

編輯#1:我嘗試重寫PORT('login/local')的路由,現在登錄,但由於某種原因,我沒有可用的req和req.user對象。一切我谷歌說,我需要包括會議,但我不使用會議,所以這不適合我。這裏的新路線:

authRoutes.post('/login/local', passport.authenticate('local', 
    function(req, res){ 
     console.log("authentication successful"); 
     var tokenObj = generateToken({email: req.body.email, displayName: req.body.DisplayName}); 
     res.status(201).json({ 
      token: 'JWT ' + tokenObj, 
      user: req.body.displayName 
     }); 
    } 
    , {failureRedirect: '/auth/notauth'} 
    , {session: false} 
)); 

有人能告訴我如何解決這一問題,使req.user將作爲每個護照文檔?

編輯#2:看來,成功函數獲取null和一個對象,其中包含來自users表的db記錄。看起來就像我在用戶成功登錄時返回的內容。不知何故,我已經打破了護照本地化,並沒有這樣做。

回答

0

得到它並具有一些改變工作:

passport.use('local', new LocalStrategy({ 
    usernameField: 'email' 
    // , passReqToCallback: false 
    , passReqToCallback: true 
    , session: false //Turn off sessions, this is a stateless REST service using JWT 
    }, 
    //function(username, password, done) { 
     function(req, username, password, done) { 
    db.users.findByEmail(username) 
     .then(function (userRecord){ 
      if (!userRecord) { return done(null, false); } 
      var pwMatch = bcrypt.compareSync(password, userRecord.password); 
      if (!pwMatch) { return done(null, false); } 
      //return done(null, userRecord); 
      return done(null, req, userRecord); 
     }) 
     .catch(function(error){ 
      return done(error); 
     }) 
    } 
)); 

authRoutes.post('/login/local', passport.authenticate('local', 
    function(err, req, userRecord){ 
     console.log("authentication successful"); 
     var tokenObj = generateToken({email: userRecord.email, displayName: userRecord.DisplayName}); 
     var res = req.res; //nfi why i need this 
     res.status(201).json({ 
      token: 'JWT ' + tokenObj, 
      user: userRecord.displayName 
     }); 
    } 
    , {failureRedirect: '/auth/notauth'} 
    , {session: false} 
));