You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js(Express+Mongoose)Facebook登录回调异常:500错误无法跳转

Facebook登录回调500错误排查与修复

我正在开发一个基于Express+Mongoose的Node.js简易应用,采用Facebook登录作为用户认证方式。用户信息已能存储到MongoDB,但Facebook回调功能异常,登录成功后无法跳转到用户页面,出现500内部服务器错误。相关代码如下:

Passport.js代码

require('dotenv').config()
const facebookStrategy = require('passport-facebook').Strategy
const User = require('./model/user.mongo')

module.exports = function(passport){
passport.use(new facebookStrategy({
clientID        : process.env.client_id,
clientSecret    : process.env.client_secret,
callbackURL     : "http://localhost:8000/auth/facebook/callback"

},
async function(token, refreshToken, profile, done) {
try{
   const user = await User.findOne({'username': profile.displayName})
   if(user)
   {
    console.log('user found')
    //console.log(user)
    return done(null,user)
   }
   else
   {
      User.create({
        username: profile.displayName
      })
      return done(null,user)
   }
}
catch(err)
{
    console.log(err)
}
console.log(profile)
}))

passport.serializeUser((user,done)=>{
done(user.id,null)
})

passport.deserializeUser(async(id, done)=>{
try
{
    const user = await User.findById(id)
    done(err, user);
}
catch(err)
{
    console.log(err)
}
})}

auth.js代码

const express = require('express')
const app = express()
const authroute = express.Router()
const passport = require('passport')

authroute.get('/',(req,res)=>{
res.render('auth')
})

authroute.get('/profile',isLoggedIn,(req,res)=>{
res.render('profile',{user:req.user})
})

function isLoggedIn(req,res,next)
{
if(req.isAuthenticated())
{
    return next()
}
return res.redirect('/auth')
}

authroute.get('/facebook',passport.authenticate('facebook',{
scope: [,'public_profile','email']
}))

authroute.get('/facebook/callback',passport.authenticate('facebook',
{ failureRedirect:       '/login', failureMessage: true }),
function(req, res) {
res.redirect('/user');
})

authroute.get('/logout',(req,res)=>{
req.logout()
res.redirect('/auth')
})

module.exports = {authroute}

index.js代码

const express = require('express')
const app = express()
app.use(express.json())
require('dotenv').config()
const path = require('path')
const http = require('http')
const helmet = require('helmet')
app.use(helmet())
const morgan = require('morgan')
app.use(morgan('common'))
const mongoose = require('mongoose')
const server = http.createServer(app)
const mongo_url = process.env.mongodb_url
const bodyParser = require('body-parser')
const {authroute} = require('./controller/auth')
const {userroute} = require('./controller/user')
const passport = require('passport')
const session = require('express-session')
const cookieParser = require('cookie-parser')
app.use(bodyParser.urlencoded({extended: true}))
app.set('views',path.join(__dirname,'views'))
app.set('view engine','ejs')

require('./passport')(passport)
app.use(session({
secret: "Harvey_Specter",
resave: false,
saveUninitialized: true,
}))
app.use(passport.initialize())
app.use(passport.session())
app.use(cookieParser())

app.use('/auth',authroute)
app.use('/user',userroute)
server.listen(8000,async(req,res)=>{
await mongoose.connect(mongo_url,{
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(()=>{
    console.log('mongodb connected')
}).catch(err=>console.log(err))
console.log('server is connected')
})

错误排查与修复方案

以下是代码中导致500错误的几个关键问题:

  1. Passport序列化函数参数顺序错误

    • 原代码:
      passport.serializeUser((user,done)=>{
      done(user.id,null)
      })
      
    • 问题:done函数参数顺序应为done(error, userIdentifier),这里颠倒了用户ID与错误参数的位置,导致Session存储异常。
    • 修复:
      passport.serializeUser((user,done)=>{
        done(null, user.id)
      })
      
  2. 反序列化函数未正确处理错误与结果

    • 原代码:
      passport.deserializeUser(async(id, done)=>{
      try
      {
          const user = await User.findById(id)
          done(err, user);
      }
      catch(err)
      {
          console.log(err)
      }
      })
      
    • 问题:try块中err变量未定义,且捕获错误后未将错误传递给done函数,导致Passport无法处理异常。
    • 修复:
      passport.deserializeUser(async(id, done)=>{
        try {
          const user = await User.findById(id)
          done(null, user); // 无错误时传递null和用户对象
        } catch(err) {
          done(err, null); // 捕获错误时传递错误对象
        }
      })
      
  3. 创建用户时未等待异步操作完成

    • 原代码:
      else
      {
         User.create({
           username: profile.displayName
         })
         return done(null,user)
      }
      
    • 问题:User.create是异步函数,未加await会导致user变量为undefined,Passport无法正确处理新用户。
    • 修复:
      else {
        const newUser = await User.create({
          username: profile.displayName
        })
        return done(null, newUser)
      }
      
  4. Facebook授权Scope数组格式错误

    • 原代码:
      scope: [,'public_profile','email']
      
    • 问题:数组开头多余的逗号会导致无效的Scope参数,引发授权流程异常。
    • 修复:
      scope: ['public_profile','email']
      
  5. 回调路由中无效的失败重定向地址

    • 原代码:
      { failureRedirect: '/login', failureMessage: true }
      
    • 问题:应用中不存在/login路由,失败时会触发404错误,进而导致500异常。
    • 修复:改为已存在的/auth路由:
      { failureRedirect: '/auth', failureMessage: true }
      
  6. 服务器监听回调参数错误

    • 原代码:
      server.listen(8000,async(req,res)=>{
      
    • 问题:server.listen的回调函数不需要req和res参数,无效参数可能引发不必要的错误。
    • 修复:去掉多余参数:
      server.listen(8000,async()=>{
      

内容的提问来源于stack exchange,提问作者sathish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 08:39:45