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

Can't get Passport.js redirect and flash message to work

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

这是我的 Express 应用程序结构:

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 ,它目前还没有 GET 方法。但是我没有得到 404 或任何东西;没有任何反应,也没有错误。非常感谢任何建议。

更新
我刚刚确认删除两个重定向会按预期导致 401 响应。此外,将 failureRedirect 设置为 /events 会产生 404,这很奇怪,因为 http://localhost:3000/events 已明确配置。

编辑
我意识到这可能有助于展示我如何在客户端进行 API 调用。按提交按钮调用以下 signup 函数:

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));
    }

你的 express 后端只是作为数据使用吗API?因为如果是,那么我不确定 PassportJS 重定向是否有效。

我记得在一个完全服务器端呈现的应用程序中使用它,路由完全在后端,这种情况使它起作用,因为任何路由都在后端处理,它呈现页面然后将其发送到客户端。

在 React 应用程序中,路由(page/url 中的实际更改)是在前端处理的,因此在 Passport 中这样做是行不通的。我认为你能做的最好的事情就是在 passport 中进行错误处理,将某种状态或消息发送到前端,然后在前端进行处理,因为那是路由所在的位置。