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

如何获取已登录用户的邮箱?基于Express+Passport的校园项目技术求助

获取已登录用户信息的解决方案

看起来你现在的核心问题是登录后无法正确获取当前用户的信息,同时代码里还有几个和数据库交互、Passport配置相关的小问题,我帮你一步步梳理修正:

核心问题:登录后用户信息的获取方式错误

你现在在/startseite路由里用req.body.email来获取用户邮箱,这是不对的——req.body只在POST请求提交表单时才有数据,登录后的用户信息Passport已经帮你存在req.user对象里了,直接用这个就行:

// 修改server.js里的startseite路由
app.get('/startseite', checkAuthenticated, (req, res) => {
  // 登录成功后,Passport会把用户信息挂载到req.user上
  res.render('startseite.ejs', { user: req.user });
  console.log(req.user); // 可以在这里打印完整的用户对象,确认数据
})

之后你在startseite.ejs里就可以直接用<%= user.email %>、<%= user.name %>来展示用户信息了。

关键修正:Passport要从数据库查询用户,而非内存数组

你现在的Passport配置里,getUserByEmail和getUserById是从内存的users数组里查的,但你的用户数据存在数据库里,这会导致登录验证和序列化/反序列化出问题,必须改成从数据库异步查询:

1. 修改server.js里的initializePassport调用

// 先确保引入db的查询方法
const { query } = require('./db');

// 替换原来的initializePassport参数
initializePassport(
  passport,
  // 从数据库按邮箱查用户(异步函数)
  async (email) => {
    const result = await query('SELECT * FROM Players WHERE email = ?', [email]);
    return result[0]; // 返回第一个匹配的用户(邮箱唯一)
  },
  // 从数据库按ID查用户(异步函数)
  async (id) => {
    const result = await query('SELECT * FROM Players WHERE id = ?', [id]);
    return result[0];
  }
)

2. 修正passport-config.js里的验证逻辑

因为现在getUserByEmail是异步函数,必须加await才能拿到用户数据:

const authenticateUser = async (email, password, done) => {
  // 必须await异步查询的结果
  const user = await getUserByEmail(email);
  if(user == null){
    return done(null, false, {message: 'Email or password incorrect'});
  }
  try {
    if(await bcrypt.compare(password, user.password)) {
      return done(null, user);
    } else {
      return done(null, false, {message: 'Email or password incorrect'})
    }
  } catch(e) {
    return done(e)
  }
}

// 反序列化用户也要改成异步,因为getUserById现在是异步函数
passport.deserializeUser(async (id, done) => {
  try {
    const user = await getUserById(id);
    done(null, user);
  } catch(e) {
    done(e);
  }
})

其他重要修正

1. 注册时的邮箱重复检查(修复语法+改用数据库查询)

你原来的循环检查有语法错误,而且用循环遍历内存数组效率极低,直接用数据库查询更可靠:

app.post('/register', checkNotAuthenticated, async (req, res, next) =>{
  try {
    // 先查数据库,看邮箱是否已存在
    const existingUser = await query('SELECT * FROM Players WHERE email = ?', [req.body.email]);
    if(existingUser.length > 0){
      console.log(`${req.body.email} email already taken`);
      // 用flash消息提示用户(需要确保你已经配置了flash中间件)
      req.flash('error', 'This email is already registered');
      return res.redirect('/register');
    }

    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    // 注意:如果你的Players表id是自增主键,这里不需要手动设置id,数据库会自动生成
    const newUser = {
      name: req.body.name,
      email: req.body.email,
      password: hashedPassword
    }

    // 用参数化查询防止SQL注入,绝对不要直接拼接字符串!
    const sql = `INSERT INTO Players (email, name, password) VALUES (?, ?, ?)`;
    await connection.query(sql, [newUser.email, newUser.name, newUser.password]);
    console.log(`User with email: ${newUser.email} inserted`);
    
    res.redirect('/login');
  } catch (err) {
    console.error(err);
    req.flash('error', 'Registration failed, please try again');
    res.redirect('/register');
  }
})

2. 修复allPlayers函数的查询逻辑

原来的query("*")是无效的,改成正确的数据库查询:

async function allPlayers(){
  try {
    const values = await query('SELECT * FROM Players');
    // 清空数组再添加,避免重复加载
    users.length = 0;
    values.forEach(user => users.push(user));
    console.log('Loaded all users from database:', users);
  } catch(err) {
    console.error('Failed to load users:', err);
  }
}

总结关键点

  • 登录后用户信息永远从req.user获取,这是Passport的标准用法
  • Passport的用户查询函数必须和数据库交互,不能依赖内存数组(重启服务器后内存数据会丢失)
  • 数据库操作一定要用参数化查询,防止SQL注入
  • 所有异步操作(数据库查询、bcrypt加密)都要正确使用await和try/catch处理异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:17:50