无法使Passport.js重定向和Flash消息正常工作

时间:2019-08-13 01:16:07

标签: javascript node.js express passport.js passport-local

我是所有Node的初学者,并尝试为我的应用配置简单的passport-local策略。我能够在数据库中创建一个新用户,但除此之外,我无法让passport.js正常工作。

这是我的快速应用程序结构:

routes
  - api
    - events.js
    - users.js
services
  - passport.js
server.js

server.js中,我分别配置路由,例如app.use('/api/users', require('./routes/api/users')。在此之前,我正在进行以下护照设置:

const session = require('express-session');
const cookieParser = require('cookie-parser');
const passport = require('passport');
const flash = require('connect-flash');

require('./services/passport')(passport);

app.use(session({ secret: process.env.SESSION_SECRET,
                  resave: true,
                  saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

我的passport.js文件如下:

const knex = require('../db/knex.js');
const LocalStrategy   = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const saltRounds = 12;

module.exports = function(passport) {

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

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

    passport.use('local-signup', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField: 'email',
        passwordField: 'password',
        passReqToCallback: true
    },
    function(req, email, password, done) {

        knex('users')
        .where({email: email}).first()
        .then(function(user) {
            if (user) { return done(null, false, {message: 'User with that email already exists!'}) }
            else {
                bcrypt.hash(password, saltRounds, function(err, hash) {
                    var newUser = new Object();
                    newUser.username = req.body.username;
                    newUser.email = email;
                    newUser.password = hash;

                    knex('users')
                        .insert(newUser)
                        .then(done(null, newUser))
                        .catch(err => { return done(err) })
                })
            }
        })
        .catch(err => { return done(err) });
    }));
};

然后在users.js中,我有:

const express = require('express');
const router = express.Router();
const knex = require('../../db/knex.js');
const passport = require('passport');
...
router.post('/signup', passport.authenticate('local-signup', {
    successRedirect: '/',
    failureRedirect: '/',
    failureFlash: true
}));

当然,我最终要使successRedirectfailureRedirect彼此不同,但是现在我只想了解如何使它们工作。如前所述,此代码成功地将用户插入数据库。但是,当我尝试使用相同的凭据创建另一个帐户时,什么也没有发生。我期望的行为是看到消息"User with that email already exists!"并被重定向到我的主页。

请注意,我的主页位于http://localhost:3000,因此不确定将重定向设置为'/'是指向该页面还是指向当前页面。当前页面是http://localhost:3000/auth,其中包含具有我的注册表单的React组件,对/api/users/signup/进行POST调用。因此可以想象'/'实际上会寻找http://localhost:3000/api/users/signup,而该404到目前为止还没有GET方法。但是我没有得到401或其他任何东西;没有任何反应,也没有错误。任何建议,不胜感激。

更新
我刚刚确认,删除这两个重定向会导致failureRedirect响应,如预期的那样。另外,将/events设置为404会产生http://localhost:3000/events,这很奇怪,因为肯定配置了signup

编辑
我意识到这可能有助于显示我如何在客户端进行API调用。按下提交按钮将调用以下signup(e) { e.preventDefault(); axios.post('/api/users/signup', { username: this.state.username, email: this.state.email, password: this.state.password }) .catch(err => console.log(err)); } 函数:

var output3 = "It is " + output3 + " days until your next Birthday";

1 个答案:

答案 0 :(得分:1)

您的Express后端是否仅用作数据API?因为如果是这样,我不确定PassportJS重定向是否可以工作。

我记得在完全由服务器端渲染的应用程序中使用了该应用程序,该应用程序的路由完全位于后端,这种情况使之可行,因为任何路由都在后端处理,并呈现页面然后将其发送给客户端。

在react应用程序上,路由(页面/ URL中的实际更改)在前端处理,因此无法在Passport中这样做。我认为您能做的最好的就是在护照中进行错误处理,该错误处理将某种状态或消息发送到前端,然后在前端进行处理,因为这就是路由所在。