无法将用户序列化到会话中,express中的passport.js本地策略

问题描述 投票:0回答:1

登录时从 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))');
}
node.js asynchronous passport.js
1个回答
0
投票

找到了:

我与键的名称不一致,忽略了数据库中的对象将不同地使用两个对象键=列名。

所以我最终使用了“username”和“uniqueuserid”而不是“name”和“id”的护照

还是非常感谢!

© www.soinside.com 2019 - 2024. All rights reserved.