登录时从 mysql 检查用户群,我从 Passport.js 收到以下错误:
错误:无法将用户序列化到会话中 通过(/NodeJS/Projects/user-management/node_modules/passport/lib/authenticator.js:296:19) 在序列化(/NodeJS/Projects/user-management/node_modules/passport/lib/authenticator.js:301:7) 在/NodeJS/Projects/user-management/src/services/passport-config.js:27:44 通过(/NodeJS/Projects/user-management/node_modules/passport/lib/authenticator.js:309:9) 在 Authenticator.serializeUser (/NodeJS/Projects/user-management/node_modules/passport/lib/authenticator.js:314:5) 在/NodeJS/Projects/user-management/node_modules/passport/lib/sessionmanager.js:33:10 在 Immediate._onImmediate (/NodeJS/Projects/user-management/node_modules/express-session/session/store.js:54:5) 在 process.processImmediate (节点:内部/计时器:476:21)
我使用了一个使用同步用户数据(只需推送到数组)的教程,并调整了代码以与来自 MYSQL 的用户数据一起使用。
如果我自己从头开始编写代码,我通常使用异步函数和等待 - 所以我不确定我在 webUsers 常量上的 .then 是否做错了什么。如果没有 .then 我会收到类型错误(不是函数),所以承诺似乎解决得很好。
您可能会注意到,我正处于编码的第一年,对于全新的主题,错误对我来说还不太明显。
我在这里做错了什么?
我的passport.js配置:
const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')
function initPassport(passport, getUserByName, getUserById) {
const authenticateUser = async (name, password, done) => {
const user = getUserByName(name)
if (user == null) {
return done(null, false, { message : 'No user with that name'})
}
try {
if (await bcrypt.compare(password, user.password)) {
return done(null, user)
} else {
return done(null, false, { message: 'Password incorrect'})
}
} catch (e) {
return done(e)
}
}
passport.use(new LocalStrategy({ usernameField: 'name'},
authenticateUser))
passport.serializeUser((user, done) => done(null, user.id))
passport.deserializeUser((id, done) => {
return done(null, getUserById(id))
})
}
module.exports = initPassport //used in routes web-user-routes , TODO: move functions to own controller and services
我的应用程序(在将其分解为控制器和服务之前使其在路线中作为一个整体工作):
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const passport = require('passport');
const flash = require('express-flash');
const session = require('express-session');
const methodOverride = require('method-override');
let { singledbentry, refresh, refreshTwo } = require("../services/db.js")
const controller = require('../controllers/web-user-controller');
const webUsers = refresh('SELECT useruniqueid, username, password, userrole, email FROM webusers')
webUsers.then((users) => {
const initPassport = require('../services/passport-config.js');
initPassport(
passport,
name => users.find(user => user.username === name),
id => users.find(user => user.useruniqueid === id)
)
})
router.use(flash())
router.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}))
router.use(passport.initialize())
router.use(passport.session())
router.use(methodOverride('_method'))
router.get('/webusers', async (_req, res, next) => {
let userData = refresh('SELECT useruniqueid, username, password, userrole, email FROM webusers')
res.render('webusers', { data: await userData });
})
router.post('/webusers', async (req, res) => {
let userUniqueId = Date.now().toString()
let userName = req.body.username
let hashedPassword = await bcrypt.hash(req.body.password, 10)
let userRole = req.body.userrole
let userEmail = req.body.email
let sql = "insert into webusers values(?,?,?,?,?)";
let sqlValues = [userUniqueId, userName, hashedPassword, userRole, userEmail];
await refreshTwo(sql, sqlValues);
let userData = refresh('SELECT useruniqueid, username, password, userrole, email FROM webusers')
res.render('webusers', { data: await userData });
})
router.post('/webusers/delete', async (req, res) => {
let deleteId = req.body.useruniqueid;
let sql = "delete from webusers where useruniqueid ='" + deleteId + "';"
await singledbentry(sql);
let userData = refresh('SELECT useruniqueid, username, password, userrole, email FROM webusers')
res.render('webusers', { data: await userData });
})
router.get('/login', checkNotAuthenticated, (req, res) => {
res.render('login.ejs');
})
router.post('/login', checkNotAuthenticated, passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true
}))
router.get('/register', checkNotAuthenticated, (req, res) => {
res.render('register.ejs');
})
router.post('/register', checkNotAuthenticated, async (req, res) => {
try {
let userUniqueId = Date.now().toString()
let userName = req.body.name
let userRole = 'USER'
let hashedPassword = await bcrypt.hash(req.body.password, 10)
let userEmail = req.body.email
let sql = "insert into webusers values(?,?,?,?,?)";
let sqlValues = [userUniqueId, userName, hashedPassword, userRole, userEmail];
await refreshTwo(sql, sqlValues);
res.redirect('/login')
} catch {
res.redirect('/register')
}
})
router.delete('/logout', (req, res) => {
req.logOut()
res.redirect('/login')
})
// Delete uses library method override and uses the following code frontend:
// <form action="/logout?_method=DELETE" method="POST">
// <button type="submit">Log Out</button></form>
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next()
}
res.redirect('/login')
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return res.redirect('/')
}
next()
}
function isAdmin(req, res, next) {
if (req.user.role === 'ADMIN') {
return next();
}
console.log('nope!')
return res.redirect('/');
}
module.exports = router;
我的 MYSQL 表设置:
// CREATE TABLES FOR <<<<< WEB-USERS >>>>> IF NOT EXIST
async function initWebUserTable() {
await pool.query ('CREATE TABLE IF NOT EXISTS webusers (useruniqueid VARCHAR(45), username VARCHAR(45), password VARCHAR(99), userrole VARCHAR(45), email VARCHAR(45), PRIMARY KEY (useruniqueid))');
}
找到了:
我与键的名称不一致,忽略了数据库中的对象将不同地使用两个对象键=列名。
所以我最终使用了“username”和“uniqueuserid”而不是“name”和“id”的护照
还是非常感谢!