Sails req.secure 详解:判断 HTTPS/WSS 安全连接及反向代理场景下的正确姿势

📅 发布时间:2026/9/20 17:19:47
Sails req.secure 详解:判断 HTTPS/WSS 安全连接及反向代理场景下的正确姿势
后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载导读req.secure是 Sails 在请求对象req上暴露的一个布尔型便捷属性用于判断当前请求是否通过安全连接https://或wss://发送。它常用于控制器、策略policies或自定义中间件中做协议级别的分支逻辑——例如强制 HTTPS、仅在加密通道下放行敏感接口、或为sails.config.session.cookie.secure提供运行时依据。读完本文你将掌握req.secure的判定原理、它与req.protocol/trust proxy的关系以及在生产环境尤其存在反向代理或负载均衡器下如何正确配置避免安全判断失效。一、属性定义与基本用法根据官方参考文档 req.secure 的定义Indicates whether or not the request was sent over a secure TLS connection (i.e.https://orwss://).即req.secure指示请求是否经由安全 TLS 连接发送——对应https://HTTP over TLS或wss://WebSocket over TLS协议。它属于req对象的只读属性在文档元数据中被标记为pageType: property而非方法因此用法是直接读取req.secure;典型返回值与语义请求类型协议req.secure值普通 HTTP 请求http://false加密 HTTP 请求https://true加密 WebSocket 请求wss://true未加密 WebSocket 请求ws://false二、判定原理从连接加密状态到req.securereq.secure并非 Sails 独立发明的新概念而是 Sails 底层的 Express 中间件/路由层为请求对象注入的标准属性。从实现上看它的取值本质上等价于对请求协议req.protocol是否为https的简写判断当 Node.js HTTP 服务器以 TLSHTTPS模式运行时底层req.connection.encrypted为真Express 据此推导出req.protocol https当请求来自加密 WebSocket 连接wss://由 Sails 的 socket 层承载时同样被视为安全连接req.secure返回true其余情况http://、ws://返回false。在 Sails 请求管道中协议信息被多处消费。例如 lib/hooks/request/metadata.js 中的_mixinServerMetadata()会依据req.protocol推导默认端口并构造req.baseUrl// Determine host port var defaultPort; if (req.protocol https || req.protocol wss) { defaultPort 443; } else { defaultPort 80; } var hostPort parseInt(host.split(/:/)[1], 10) || defaultPort; req.port hostPort; // Determine appropriate baseUrl req.baseUrl req.protocol :// host;可以看到安全协议https/wss对应的默认端口是 443非安全协议http/ws对应 80同时req.baseUrl也会带上协议前缀。这与req.secure的判定逻辑同源——都是基于req.protocol是否属于加密协议。因此理解req.protocol与req.secure的联动关系是正确使用后者的前提。可参考同目录下的 req.protocol 文档做对照阅读。另外在 lib/hooks/request/index.js 中Sails 只为符合协议条件的请求注入 HTTP 相关语法糖// Only apply HTTP-focused middleware if it makes sense // (i.e. if this is an HTTP request) if (req.protocol http || req.protocol https) { _mixinReqQualifiers(req, res); }这说明req.protocol以及它衍生出的req.secure是 Sails 路由中间件区分真正的 HTTP 请求与虚拟请求、socket 请求的重要依据之一。三、实战用法在控制器与策略中判断安全连接3.1 在控制器/动作中强制 HTTPS最常见的场景是在动作actions或控制器方法中对敏感操作强制要求安全连接// api/controllers/account/change-password.js module.exports { friendlyName: Change password, description: Update the password for the logged-in user., exits: { badRequest: { responseType: badRequest }, }, fn: async function (changePasswordInputs) { if (!this.req.secure) { throw badRequest; // 或执行 res.redirect(https:// ...) } // ... 执行密码修改逻辑 return { success: true }; }, };3.2 在策略policies中统一拦截明文请求更优雅的做法是把协议检查下沉到 策略层对所有挂载该策略的路由统一生效// api/policies/require-https.js module.exports function requireHttps(req, res, next) { if (!req.secure) { return res.redirect(https:// req.get(Host) req.url); } return next(); };// config/policies.js module.exports { *: false, checkout/*: require-https, };这种方式无需在每个动作里重复编写判断且便于统一调整策略。注意req.get(Host)取到的是 Host 头中的主机名不含协议拼接时需按实际情况处理端口。四、关键陷阱反向代理 / 负载均衡器下的trust proxy配置4.1 问题根源当应用部署在 Nginx、HAProxy、AWS ELB 等反向代理之后时Node.js 服务器实际收到的连接来自代理通常是本机明文 HTTP此时服务器看到的底层连接未加密 →req.protocol会被推导为http→req.secure false真实的客户端协议信息https由代理通过X-Forwarded-Proto请求头传递给后端若不信任该请求头Sails/Express 会无视它导致req.secure恒为false进而引发强制跳转死循环、安全策略误判等问题。这正是 lib/hooks/request/metadata.js 中注释所强调的We trust req.protocol to be set by Express when trust proxy is enabled.也就是说只有当trust proxy启用时Express 才会参考X-Forwarded-Proto等头来推导协议Sails 才会据此得到正确的req.secure。4.2 Sails 中的配置入口Sails 的 HTTP 钩子在 lib/hooks/http/index.js 中声明了默认值并对非法取值做了校验// (this is passed in to Express as the trust proxy setting) trustProxy: false,校验逻辑要求该值不能是0、空字符串、null或NaN并在错误信息中提示如果应用直接面向公网应保持trustProxy: false。随后在 lib/hooks/http/initialize.js 中该配置被真正写入 Express 应用// Set Express trust proxy if appropriate. if (sails.config.http.trustProxy) { expressApp.set(trust proxy, sails.config.http.trustProxy); }因此若你的应用部署在可信的反向代理之后应在 config/http.js 中显式开启// config/http.js module.exports.http { trustProxy: true, // 信任反向代理传递的 X-Forwarded-* 头 middleware: { // ... 其他中间件配置 }, };开启后Express 会依据X-Forwarded-Proto推导req.protocolreq.secure随即返回正确的true。4.3 联动安全 Cookie 与req.secure的配合req.secure还与 会话session 的安全 Cookie 配置紧密相关。在 lib/hooks/session/index.js 中Sails 会对sails.config.session.cookie.secure做严格的类型校验与提醒若cookie.secure被指定但不是布尔值直接抛出异常必须是true或false若应用使用 HTTPS 且依赖反向代理Sails 会提示你同时把sails.config.http.trustProxy设为true否则 Express 无法获知真实的加密协议req.secure可能为false导致安全 Cookie 无法按预期工作若cookie.secure已设为trueSails 会提示该 Cookie 只会在https://即req.secure true连接上被发送。典型配置// config/session.js module.exports.session { cookie: { secure: true, // 仅通过 HTTPS 发送会话 Cookie }, };五、测试验证req.protocol与req.secure的行为证据Sails 仓库的单元测试 test/hooks/request/req.metadata.test.js 直接验证了基于req.protocol的协议推导行为。测试先构造req.protocol https注释明确写着we assume Express got this right即把协议判定视为 Express 层已正确处理的前提然后断言派生出的端口与 baseUrlit(should handle a simple HTTPS case with X-Forwarded-Host, function() { this.req.protocol https; // we assume Express got this right this.req.host server.local; this.req.headers.Host server.local; this.req.headers[X-Forwarded-Host] example.org; mixinMetadata(this.req); assert.equal(this.req.port, 443); // https 默认端口 443 assert.equal(this.req.baseUrl, https://example.org); // baseUrl 带 https 前缀 });其中还覆盖了X-Forwarded-Host缺失、多值example.org, server1.local取第一项、非标准端口、反向代理携带端口等边界情形并从 lib/hooks/request/metadata.js 的trustProxy读取逻辑可见只有trustProxy为真时X-Forwarded-Host才会被采纳。这一测试佐证了req.secure体系的完整链路底层 TLS 状态 /X-Forwarded-Proto→req.protocol→req.secure、req.port、req.baseUrl。六、使用注意事项小结req.secure是派生属性而非原始信息它的正确性取决于 Express 推导req.protocol时掌握的信息直接面向公网时通常准确处于代理之后时必须开启sails.config.http.trustProxy。不要手动解析X-Forwarded-Proto代替它解析代理头存在被伪造的风险应由trust proxy统一管理信任边界若使用trustProxy: true的宽松信任策略请确保只有可信代理能直连你的应用。WebSocket 场景同样适用wss://连接下req.secure同样为true可在 socket 相关的动作 中复用协议判断逻辑。与安全 Cookie 联动启用cookie.secure时务必确认部署链路中req.secure的真实取值避免安全 Cookie 在代理环境下永远发不出去或明文传输。相关参考属性定义req.secure协议对照req.protocol服务端元数据注入实现lib/hooks/request/metadata.jsHTTP 钩子与trustProxy配置lib/hooks/http/index.js、lib/hooks/http/initialize.js、sails.config.http会话安全 Cookie 校验与提示lib/hooks/session/index.js、sails.config.session相关测试用例test/hooks/request/req.metadata.test.js赞分享后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载相关推荐Sails req.ip 完全指南获取请求客户端 IP 及反向代理场景下的正确配置Sails req.ip 完全指南获取请求客户端 IP 及反向代理场景下的正确配置 在 SailsRealtime MVC Framework for No后端Gulp 中的 Vinyl.isVinyl()判断 Vinyl 实例的正确姿势Gulp 中的 Vinyl.isVinyl 判断 Vinyl 实例的正确姿势 Vinyl.isVinyl 是 vinyl https://link.gitco构建工具CLIReflex Enterprise 认证部署到生产环境指南HTTPS、回调 URL 与反向代理下的 OIDC 正确姿势Reflex Enterprise 认证部署到生产环境指南HTTPS、回调 URL 与反向代理下的 OIDC 正确姿势 reflex enterprisev后端前端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考