req.user 使用快速服务器进行 Twitter 身份验证后未定义,passport.js

req.user undefined after twitter authentication using express sever, passport.js

关于在社交身份验证后获取 req.user undefined 有很多问题,但我发现 none 可以帮助我。

我已经能够成功使用使用护照进行 Twitter 身份验证的示例:https://github.com/passport/express-4.x-twitter-example。我试图尽可能地遵循这种模式,但似乎无法让它发挥作用。

具体来说,我能够成功验证,但 req.user 未定义。这对我来说毫无意义,因为我的用户数据从示例中返回没有问题。

我不倾向于认为这是一个中间件问题(就像其他人一样),因为中间件与示例中使用的相同。这可能与拥有多个域有关,但我不确定是什么。所有这些都在本地主机上完成。

在 Twitter 中,应用程序设置为 网站是:127.0.0.1:3000/signin 和 回调 url 是:127.0.0.1:2999/auth/twitter/return

如您所知,我的客户端正在端口 3000 上工作,它正在调用端口 2999 上的服务器 运行。

为了简要介绍代码,127.0.0.1:3000/signin 上的客户端有一个链接到 127.0.0.1:2999/auth/twitter 的按钮,从而启动身份验证请求。在幕后,快速服务器是在 server/index.js--server 中创建的。这会在 routes/index.js 中导入路由,其中​​一些由控制器 authenticate.js 处理。如您所见,oauth twitter 请求是在 authenticate.js 中发出的。同样,身份验证成功进行,我被重定向到 127.0.0.1:3000/search。但是,正如您在 this.twitter_callback 中看到的,我正在打印 req.user 并且它是未定义的。

请注意,我已经从我的代码中编辑了消费者 key/secret。

server/index.js

var cors = require('cors')
var bodyParser = require('body-parser')
var express = require('express');
var app = express();
var http = require('http').Server(app)
var io = require('socket.io')(http)
// NOT SURE WHY I NEED TO GO BACK 3 FOLDERS TO GET TO PORT_CONFIG
var port = require("../port_config.json").server_port;
var PORT = Number(process.env.PORT || port);
var routes = require('./routes/index.js')
var database = require('./database/db.js')
var db = new database()

app.use(cors()); // middleware that allows cross-platform requests
app.use(bodyParser.json());

db.dbConnect(function(err,db_instance){
    // routes
    routes(app, db_instance, io)
    // send user polls on connection 
    // TEMPORARY (WILL BE GRABBED ON LOGIN)
    var user = null // WILL BE SET AFTER LOGIN
    io.on('connection', function(socket) {
    var places_attending = db_instance.collection('places_attending')
    places_attending.find({}).toArray(function(err,docs){
        var places_user_attending = docs.map(doc => {
            if (doc.attending.indexOf(user) !== -1) {
                return {
                    id: doc.id,
                    name: doc.name,
                    num_attending: doc.attending.length
                }
            }
        })
        socket.emit('places_user_attending', places_user_attending);
    })
    })
})

http.listen(PORT, function () {
    console.log('Backend server listening at http://localhost:' +     PORT);
})

module.exports = http

routes/index.js

var Search = require('../controllers/search.js')
var Add = require('../controllers/add.js')
var Authenticate = require('../controllers/authenticate.js')


module.exports = function(app, db, io) {
    var search = new Search(db, io)
    var add = new Add(db, io)
    var authenticate = new Authenticate(app)

    app.route('/api/search')
        .post(search.search_yelp)

    app.route('/api/add')
        .post(add.add_attendee)

    app.route('/auth/twitter')
        .get(authenticate.twitter_authentication) 

    app.route('/auth/twitter/return')
        .get(authenticate.twitter_callback)
}

authenticate.js

function authenticate(app) {

var passport = require('passport');
var Strategy = require('passport-twitter').Strategy;


// Configure the Twitter strategy for use by Passport.
passport.use(new Strategy({
    consumerKey: REDACTED,
    consumerSecret: REDACTED,
    callbackURL: 'http://127.0.0.1:2999/auth/twitter/return'
  },
  function(token, tokenSecret, profile, cb) {
    // In this example, the user's Twitter profile is supplied as the user
    // record.  In a production-quality application, the Twitter profile should
    // be associated with a user record in the application's database, which
    // allows for account linking and authentication with other identity
    // providers.
    return cb(null, profile);
  }));


// Configure Passport authenticated session persistence.
passport.serializeUser(function(user, cb) {
  cb(null, user);
});

passport.deserializeUser(function(obj, cb) {
  cb(null, obj);
});


// Use application-level middleware for common functionality, including
// logging, parsing, and session handling.
app.use(require('morgan')('combined'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave:     true, saveUninitialized: true }));

// Initialize Passport and restore authentication state, if any, from the
// session.
app.use(passport.initialize());
app.use(passport.session());

this.twitter_authentication = passport.authenticate('twitter')

this.twitter_callback = (
  passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
  function(req, res) {
       console.log('REQ.USER OBJECT: ' + req.user)
       res.redirect('http://127.0.0.1:3000/search');
   }
)

}

module.exports = authenticate

如有任何帮助,我们将不胜感激。

问题在于我的 twitter_callback 路线是如何指定的。

如果我将回调更改为:

this.twitter_callback = app.get('/auth/twitter/return',
passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
function(req, res) {
console.log(req.user)
res.redirect('http://127.0.0.1:3000/search');
})

一切正常。我认为这与我最初编写中间件时未正确应用中间件有关。不完全确定我将如何重写它以导出它,尽管

在 twitter_callback 中不使用 app.get