【问题标题】:nodejs passport callback not being called未调用nodejs护照回调
【发布时间】:2020-09-21 20:58:52
【问题描述】:

我对 JS 和 NodeJs/Express 都很陌生。我正在编写一个概念证明 MVP 节点/快速应用程序,它使用护照进行身份验证(通过社交登录)。

我已经编写了服务器并安装了所有必需的软件包以及到目前为止的所有内容(除了身份验证位有效)。

注意:我已经在各个社交媒体公司设置了我的凭据,所以这不是问题。

这是我的代码的 sn-p:

app.js

const express = require('express');
const expressLayouts = require('express-ejs-layouts');
compression = require('compression'),
shouldCompress = (req, res) => {
    if (req.headers['x-no-compression']) {
      // don't compress responses if this request header is present
      return false;
    }
    // fallback to standard compression
    return compression.filter(req, res);
  };

const app = express();

// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');

// Parsing related
app.use(express.urlencoded( { extended: false })); //Parse URL-encoded bodies
app.use(express.json()); //Used to parse JSON bodies

app.use(compression({
    filter:shouldCompress,
    threshold: 3
}));

app.use(express.static('public'));
app.disable('x-powered-by');

// Initialize Passport and restore authentication state, if any, from the session.
var passport = require('passport');
app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session())

// Routes
app.use('/', require('./routes/index'));
app.use('/member', require('./routes/users'));


const PORT = process.env.PORT || 5000;

app.listen(PORT, console.log(`Server started on port: ${PORT}`));

路由/users.js

const express = require('express');
const router = express.Router();

/* GET authentication funcs */
let authentication = require('../controllers/auth.js');

router.get('/subscribe', (req, res) => { res.render('subscribe'); });
router.post('/subscribe', authentication.subscribe);

module.exports = router;

控制器/auth.js

require('dotenv').config();
const model = require("../models");

const passport = require('passport');

const LocalStrategy = require('passport-local').Strategy;
const FacebookStrategy = require('passport-facebook').Strategy;

passport.serializeUser(function(user, done) {
    done(null, user)
});


passport.deserializeUser(function(email, done) {
    done(null, email)
})


function validateLead(req, done) {
    mail = req.body.lead_email;
    console.log('validateLead() called!');

    models.Lead.findOne({
        where: {
            email: email
        }
    }).then(/* some logic */).catch();
        } else {
            // email already taken ..
            return done(null, false, {
                message: 'This email address is already subscribed'
            });
        }
    }).catch((err) => {
        console.log('An error occurred!', err);
    });
}

exports.subscribe = function(req, res, next) {
    switch (req.body.source) {
        case 'facebook':
            passport.use(new FacebookStrategy({
                    clientID: process.env.FACEBOOK_APP_ID,
                    clientSecret: process.env.FACEBOOK_APP_SECRET,
                    callbackURL: process.env.FACEBOOK_CALLBACK_URL
                },
                function(accessToken, refreshToken, fbProfile, done) {
                    console.log('FB callback!');
                    profile = {
                        'email': fbProfile.email,
                        'firstName': '',
                        'LastName': '',
                        'leadSource': '',
                        'tags': [],
                    };
                    return validateLead(req, done, profile);
                }
            ));
            break;
        default:
            console.log('Unknown');
      }
}

views/test.eps

<a href='#'><i id='facebook' class='foobar'></i></a>

(简化)views/layout.eps

   $(document).ready(function(){
      $('i.foobar').click(function(e){
        $.ajax({
          method: "POST",
          url: "/member/subscribe",
          data: {
            "source": $(this).attr('id')
          },
          dataType: "json",
          timeout: 5000 // 5000ms
        }).done(function(data) {
          // is called if request is successful
          console.log(data.fridge);
        }).fail(function(jqXHR, status) {
          // is called if request fails or timeout is reached
          alert('Request could not complete: ' + status);
        });
      });
    });

我已将 console.log() 消息放入 controllers/auth.js 中,我可以看到正在到达 FB 代码分支。但是,当 validateLead() 中的日志消息和 FB 回调函数未到达时。

这是什么原因,我该如何解决?

【问题讨论】:

  • 你能把这个放到一个codesandbox里吗?调试起来会容易得多。

标签: javascript node.js passport.js passport-facebook


【解决方案1】:

我可以看到几件事:

据我所知,您没有配置passportjs。你需要有一个配置文件,对你来说是controllers/auth.js。要配置护照,您需要在app.js 中运行require('./controllers/auth')(passport);

要让护照能够摄取该配置,您需要将它们导出为需要护照的功能,例如module.exports = passport =&gt; {passport.use('facebook')}

您的配置文件(exports.subscribe)不是护照可以理解的格式。按照文档了解如何创建该配置文件。


Passport 为您提供身份验证中间件,我很确定您不能像在controllers/auth.js 中那样为它们创建“包装器”。要访问护照的身份验证功能,请在 routes/users.js 中使用 passport.authenticate('facebook', callback())(req, res, next)

Passport 只提供了对用户进行序列化和反序列化的中间件。


您的反序列化尚未设置。您需要调用数据库以从会话存储中获取用户。

【讨论】:

  • 谢谢,这是一个很好的起点。但是,当我尝试按照您建议的方式配置护照时,出现以下错误:TypeError: require(...) is not a function
  • Nodejs 应该有 require() 可用...我需要查看您的整个应用程序以帮助您解决该错误。
猜你喜欢
  • 1970-01-01
  • 2018-03-15
  • 2016-12-14
  • 1970-01-01
  • 2017-10-05
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多