Nextjs 和 Passport 身份验证:无法将用户从会话中反序列化

Nextjs and Passport authentication: Failed to deserialize user out of session

尝试了几天后,我需要一些帮助。

我正在使用护照在我的 nextjs 应用程序中设置身份验证。登录后,会话存储在我的数据库中,用户对象位于 req 对象上。 问题是在浏览器或服务器重新启动后,使用 auth.js 中间件时 returns 错误消息“无法反序列化用户退出会话”。

用户登录端点

// pages/api/auth/login.js

import nextConnect from 'next-connect'
import '../../../lib/passport-local'
import passport from 'passport'
import auth from '../../../middleware/auth'
const jwt = require('jsonwebtoken');
require('dotenv').config();

const handler = nextConnect()

handler.use(auth).post(
  (req, res) => {
    passport.authenticate(
      'local',
      (err, user, {message}) => {
        try {
          if (err || !user) {
            return res.json({ error: message });
          }
          req.login(
            user,
            (error) => {
              if (error) return res.json({ error });

              let { id, email, firstname, lastname } = user
              return res.json({message: "Logged in",user: {id, email, firstname, lastname} });
            }
          );
          // let { id, email, firstname, lastname } = user
          // return res.json({message: "Logged in",user: {id, email, firstname, lastname} });
        } catch (error) {
            return res.json({error});
        }
      }
    )(req, res);
  }

护照攻略:

// lib/passport-local.js
 
import passport from 'passport'
const LocalStrategy = require('passport-local').Strategy
const  Sequelize  = require('sequelize');
const models = require('./../db/models/index');

require('dotenv').config();

passport.use(new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password'
},
  async (email, password, done) => {
    try {
        let user = await models.User.findByMail(email) || false
        if (!user) {
          return done(null, false, {message: 'User not found'} );
        }
        const validate = await user.isValidPassword(password);
        if (!validate) {
          return done(null, false, {message: 'Wrong Password'} );
        }        
        return done(null, user, {message: 'Logged in Successfully'} );
    } catch (error) {
      return done(error);
    }
  }
));

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

passport.deserializeUser(async (id, done) => {
    try{
      let user = await models.User.findByPk(id)

      done(null, {id: user.id, firstname: user.firstname, lastname: user.lastname, email: user.email});
    } catch (error) {
      done(error);
    }

});

授权中间件:

// middelware/auth.js

import nextConnect from 'next-connect'
import passport from 'passport'
import db from './../db/models/index'
var session = require('express-session');
var SequelizeStore = require("connect-session-sequelize")(session.Store);

var myStore = new SequelizeStore({
  db: db.sequelize,
  checkExpirationInterval: 15 * 60 * 1000, // The interval at which to cleanup expired sessions in milliseconds.
  expiration: 24 * 60 * 60 * 1000  // The maximum age (in milliseconds) of a valid session.
})

const auth = nextConnect()
  .use(
    session({
      name: 'as-auth',
      saveUninitialized:true,
      secret: process.env.TOKEN_SECRET,
      store: myStore,
      resave: false,
      cookie: {
        maxAge: 60 * 60 * 1000, // 1000 hours,
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        path: '/',
        sameSite: 'lax',
      },
    })
  )
  .use(passport.initialize())
  .use(passport.session())
  myStore.sync();

export default auth

检查用户是否登录的端点

// pages/api/auth/loggedin.js

import nextConnect from 'next-connect'
import auth from '../../../middleware/auth'

const handler = nextConnect()

handler
  .use(auth)
  .get((req, res) => {
    res.json({ user: req.user })
  })

export default handler

已修复:这是因为我忘记在middelware/auth.js中导入passport-local,所以我的中间件没有序列化和反序列化功能。