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

Prisma与Express中req.session.user返回undefined的问题求助

问题:SolidJS图书应用中用户会话获取失败(getUser返回undefined)

问题描述

我正在开发一个基于SolidJS(类React框架)的图书搜索应用,需要实现用户会话功能:用户登录后,获取用户ID或用户名展示在头部组件,同时用于关联用户点赞的图书。但在GET路由对应的getUser控制器中尝试获取这些信息时,控制台返回undefined。

上下文代码(UserController.js)

const  { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient()
const bcrypt = require('bcrypt')

exports.signUpUser = async (req, res) => {
    const {
        id,
        username,
        email,
        password,
    } = req.body

    // Validações
    if(!username){
        return res.status(422).json({ msg: "O seu nome é obrigatório!"})
    }
    if(!email){
        return res.status(422).json({ msg: "O email é obrigatório!"})
    }
    if(!password){
        return res.status(422).json({ msg: "A senha é obrigatória!"})
    }

    //Checar se o usuário existe
    const checkUser = await prisma.user.findUnique({
        where: {
            email: email
        }
    })

     if(checkUser){
            return res.json({ error: "Email ja cadastrado!"})
        }

    // Criar senha
    const salt = await bcrypt.genSalt(12)
    const hasspassword = await bcrypt.hash(password, salt)

    try {
        const user = await prisma.user.create({
            data: {
                id,
                username,
                email,
                password: hasspassword,
            } 
        })
    
        res.status(201).json(user).send({status: "ok"})
    } catch (error) {
        res.status(400).send({ status: "error" }, error)
    }
}

exports.userLogin = async (req, res) => {
    const { email, password } = req.body

    if(!email){
        return res.status(422).json({ msg: "O email é obrigatório!"})
    }
    if(!password){
        return res.status(422).json({ msg: "A senha é obrigatória!"})
    }

    const user = await prisma.user.findUnique({
        where: {
            email
        }
    })
    
    if(!user) {
        return res.status(404).json({ msg: "Usuario não encontrado!"})
    }

    // Checar se as senhas conferem
    const checkPassword = await bcrypt.compare(password, user.password)

    if(!checkPassword){
        return res.status(422).json({ msg: "Senhas inválida!"})
    }

    req.session.user = user;
    console.log(req.session.user)

    try {
        req.session.loggedin = true  
        res.status(200).json({ msg: "Autenticação realizada com sucesso"})
    } catch (error) {
        res.status(400).json({ msg: error.message })
    }
}

exports.getUser = async (req, res) => {  
        const ses = req.session.user 
        try{
            console.log(ses)
        }catch(error){
            console.log(error)
        }
  };

可能的原因及解决方案

1. 会话中间件未正确配置

Express本身不会处理会话,必须依赖express-session中间件,且要确保在路由之前加载。

修复步骤:
在Express主入口文件中添加会话配置:

const session = require('express-session');

// 必须在所有路由注册前配置会话中间件
app.use(session({
  secret: 'your-secure-secret-key', // 替换为随机生成的安全密钥
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production', // 生产环境需开启HTTPS并设置为true
    sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 跨域场景需设为'none'(配合secure: true)
    maxAge: 24 * 60 * 60 * 1000 // 会话有效期1天
  }
}));

2. 前端请求未携带会话Cookie

SolidJS前端发起请求时,若未设置携带Cookie,后端无法识别会话。

修复步骤:
在前端请求getUser接口时,添加凭证携带配置:

// SolidJS中使用fetch的示例
const fetchUser = async () => {
  const response = await fetch('/api/user', {
    credentials: 'include' // 确保携带会话Cookie
  });
  const data = await response.json();
  // 处理用户数据,比如更新状态展示用户名
};

3. getUser控制器未正确处理响应

当前控制器仅打印会话信息,未向前端返回数据,同时未处理会话不存在的场景。

修复步骤:
修改getUser控制器:

exports.getUser = async (req, res) => {  
  const user = req.session.user;
  if (!user) {
    return res.status(401).json({ msg: '用户未登录' });
  }
  // 过滤敏感信息(如密码)后返回
  const { password, ...safeUser } = user;
  res.status(200).json(safeUser);
};

4. 会话存储配置问题(生产环境)

默认的内存会话存储在生产环境不稳定,容易导致会话丢失,建议使用持久化存储(如Redis)。

示例配置(使用connect-redis):

const RedisStore = require('connect-redis').default;
const redis = require('redis');

const client = redis.createClient({
  // Redis连接配置
});
client.connect().catch(console.error);

app.use(session({
  store: new RedisStore({ client }),
  secret: 'your-secure-secret-key',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,
    sameSite: 'none',
    maxAge: 24 * 60 * 60 * 1000
  }
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:49:50