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

客户端能否访问res.locals中存储的hashpassword等敏感字段?

问题背景

我在服务端把完整的user对象存在res.locals.loggedUser里,实现代码如下:

app.use(async (req, res, next) => {
     const user = await User.findById(req.session.userid);
     res.locals.loggedUser = user;
     next();
});

设置完res.locals.loggedUser之后,我可以在EJS模板里按如下方式访问数据,最终渲染后返回给客户端:

<% if(loggedUser) { %>
     <p>Your name: <%= loggedUser.name %></p>
<% } %>

完整的user对象包含以下字段:

_id: {
        ObjectId("123abc")
    },
    name: {
        type: String,
        required: [true, 'Your name is required.']
    },
    email: {
        type: String,
        required: [true, 'Email cannot be blank.'],
        unique: true
    },
    phone: {
        type: Number,
        required: [true, 'You must provide your phone number.'],
        unique: true
    },
    hashpassword: String,
    date: {
        joined: {
            type: Date
        }
    },
疑问

客户端能不能拿到user对象的其他字段,比如hashpassword?还是说res.locals只有服务端能访问?


解答

res.locals是仅服务端渲染模板时可访问的上下文变量,默认不会直接暴露给客户端,分两种情况判断是否会泄露敏感字段:

  • 如果你当前的EJS模板和示例写法一致,只主动输出name这类需要的字段,客户端完全拿不到hashpassword等其他字段:EJS的模板逻辑全部在服务端执行,最终返回给浏览器的只有渲染完成的静态HTML,里面只会包含你主动输出的内容,其余res.locals里的字段不会出现在响应包中。
  • 如果你在模板里主动把完整的user对象序列化输出,比如写了<%= JSON.stringify(loggedUser) %>把对象塞进前端JS变量或者页面文本里,那客户端就能拿到所有字段,包括hashpassword,会有严重的安全风险。

最佳实践建议

哪怕现在没有泄露风险,也建议你在给res.locals.loggedUser赋值的时候就过滤掉敏感字段,从根源避免后续写模板时不小心泄露:

// 只取需要的字段存入,去掉hashpassword等敏感内容
const { hashpassword, ...safeUser } = user.toObject();
res.locals.loggedUser = safeUser;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:06:09