无法使 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
}));
当然,我最终会想让 successRedirect
和 failureRedirect
彼此不同,但现在我只想了解如何让它们工作。正如我所提到的,这段代码成功地将一个用户插入到数据库中。但是当我尝试使用相同的凭据创建另一个帐户时,没有任何反应。我期望的行为是看到消息 "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 中进行错误处理,将某种状态或消息发送到前端,然后在前端进行处理,因为那是路由所在的位置。
我是 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
}));
当然,我最终会想让 successRedirect
和 failureRedirect
彼此不同,但现在我只想了解如何让它们工作。正如我所提到的,这段代码成功地将一个用户插入到数据库中。但是当我尝试使用相同的凭据创建另一个帐户时,没有任何反应。我期望的行为是看到消息 "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 中进行错误处理,将某种状态或消息发送到前端,然后在前端进行处理,因为那是路由所在的位置。