javascript - Passport 身份验证回调挂起

标签 javascript node.js express mongoose passport.js

几个小时后,我试图自己解决这个问题,然后我来到 SO 社区寻找一些线索。

我正在使用 Passport 进行用户身份验证。它已经根据文档在我的主要 express.js 文件中初始化:

app.use(passport.initialize());

我得到了一个 index.js 文件,它以这种方式处理 facebook-passport: 索引.js

'use strict';

import express from 'express';
import passport from 'passport';
import auth from '../auth.service';
let router = express.Router();

//this function is defined in the auth.service import but copied it here in case it's needed (the `signToken` is also defined in the service)
function setTokenCookie(req, res) {
  if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'});
  var token = signToken(req.user._id, req.user.role);
  res.cookie('token', JSON.stringify(token));
  res.redirect('/');
}


router
  .get('/', passport.authenticate('facebook', {
    scope: ['email', 'user_about_me'],
    failureRedirect: '/login'
  }))

.get('/callback', passport.authenticate('facebook', {
  successRedirect: '/',
  failureRedirect: '/login'
}), setTokenCookie);

module.exports = router;

以及以这种方式导入到 index.js 中的 passport.js:

Passport .js

import passport from 'passport';
import {
  Strategy as FacebookStrategy
}
from 'passport-facebook';

exports.setup = function(User, config) {
  passport.use(new FacebookStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret,
      callbackURL: config.facebook.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'facebook.id': profile.id
      }, (findErr, user) => {
        if (findErr) {
          return done(findErr);
        }
        if (!user) {
          let userToSave = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            role: 'user',
            username: profile.username,
            provider: 'facebook',
            facebook: profile._json
          });
          userToSave.save((saveErr) => {
            if (saveErr) done(saveErr);
            return done(null, user);
          });
        } else {
          return done(null, user);
        }
      });
    }
  ));
};

这是目前发生的事情:

  • 提示 Facebook 登录
  • 在 Facebook 中成功验证后,回调 (/auth/facebook/callback) 会按预期到达用户信息和 token 。
  • 用户被保存在具有预期字段的数据库中

事情变得奇怪的地方:

  • 保存用户后,done(null,user) 什么都不做。应用挂起回调,客户端一直等待响应。
  • 中间件 setTokenCookie 从未被调用,所以问题肯定出在上一步。

我尝试过的:

  • passport.js 中的整个设置函数包装在一个 process.tick 中(发现有人使用它但没有解决问题)
  • 使用 Mongoose 和 User.findOne({...}).exec().then(user => {...})
  • 中的 promise

如果您需要更多信息,请随时询问。非常感谢任何帮助。

谢谢!

最佳答案

我看到我的代码中有一些可能遗漏的部分。您使用的是 passport.session() 中间件吗?还有 serializeUserdeserializeUser 函数吗?

passport.serializeUser(function(user, done) {
  //place user's id in cookie
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  //retrieve user from database by id
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

关于javascript - Passport 身份验证回调挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32619736/

相关文章:

javascript - Ajax无限滚动图库多次添加相同的图像

javascript - 如果失败,则跳过规范中的后续 Mocha 测试

javascript - 将嵌套数组转换为对象,将数组索引与对象 ID 匹配

javascript - 如何正确使用Express 4多路路由器

javascript - 使用 Express 从 Javascript 向 Node.js 发送/接收数据

javascript - rails 5 : JS treeview from hash of dates

javascript - 通过 REST API 在 BlockBlob 上设置 Azure 元数据

javascript - 滚动不透明度转移到目标元素和从目标元素转移

javascript - 尝试转换为 mp3 时产生 ENOENT 错误

javascript - 快速错误处理 : Sending a Message to Frontend