后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载安全钩子security hook是 Sails 框架内置的核心钩子之一负责两大职责为应用绑定跨域资源共享CORS所需的 shadow routes影子路由与响应头处理以及生成security/grant-csrf-token动作用于发放 CSRF 令牌。本文以 lib/hooks/security/README.md 为主线结合该钩子的源码实现lib/hooks/security/index.js 及cors/、csrf/子模块完整讲解其隐式默认配置、加载依赖、路由绑定原理并给出可直接落地的config/security.js与config/routes.js配置示例帮助你精确控制 Sails 应用的跨域策略与 CSRF 防护。钩子概览与定位security是 Sails 的一个核心钩子Core Hook定义于 lib/hooks/security/index.js。在 Sails 的钩子体系中核心钩子统一在 lib/hooks/index.js 中装配security 钩子在整个应用启动流程中的职责非常聚焦只有两条绑定 shadow routes 以设置正确的 CORS 响应头当 Sails 加载时该钩子监听router:before事件从而在路由器绑定显式路由之前先完成自身路由的绑定随后依据sails.config.cors并混入其隐式默认值为合适的端点绑定 CORS shadow routes。设置 CSRF 动作生成并注册security/grant-csrf-token动作供前端通过 HTTP 请求获取 CSRF 令牌。从 lib/hooks/security/index.js 的initialize实现可以看到初始化顺序为先调用initializeCors()再调用initializeCsrf()最后通过registerActions()调用sails.registerAction(grantCsrfToken, security/grant-csrf-token)注册令牌发放动作registerAction的通用机制可参考 docs/reference/application/sails.registerAction.md。稳定级别该钩子稳定性评级为Stable2稳定级说明其 API 与行为在后续版本中会保持向后兼容可以放心用于生产环境。稳定性索引的完整分级说明见 docs/contributing/stability-index.md。加载依赖与依赖方在钩子加载顺序方面security 钩子明确声明了前置依赖与下游依赖方向钩子说明依赖Dependenciesmoduleloader、userconfig本钩子加载前这两个钩子必须已加载完成依赖方DependentsN/A禁用本钩子不会强制要求禁用其他核心钩子依赖moduleloader与userconfig的原因从代码结构可以推断本钩子的配置sails.config.security来自用户项目配置文件需要userconfig先完成用户配置的装载而路由绑定、动作注册依赖模块加载机制与sails.registerAction这与moduleloader的加载次序有关。同时lib/hooks/security/index.js 中还有一个硬性校验当sails.config.security.csrf true且sails.hooks.session不存在时会直接抛出E_INVALID_SECURITY_CONFIG错误因为CSRF 支持依赖 session 钩子必须启用session 配置可参考 docs/reference/sails.config/sails.config.session.md 与 docs/anatomy/config/session.js.md。隐式默认配置Implicit Defaults该钩子通过defaults属性lib/hooks/security/index.js在sails.config.security上设置如下隐式默认配置这些默认值会在用户配置之前先注入用户配置随后覆盖之属性类型默认值sails.config.security.cors.allowOrigins((string))*sails.config.security.cors.allRoutes((boolean))falsesails.config.security.cors.allowCredentials((boolean))falsesails.config.security.cors.allowRequestMethods((string))GET, HEAD, PUT, PATCH, POST, DELETEsails.config.security.cors.allowRequestHeaders((string))content-typesails.config.security.cors.allowResponseHeaders((string))空字符串sails.config.security.cors.allowAnyOriginWithCredentialsUnsafe((boolean))falsesails.config.security.csrf((boolean))false逐项解读其实际含义allowOrigins允许跨域访问的来源列表。默认*表示允许任意来源。注意源码中有一个兼容处理若传入的是非*的字符串会按逗号拆分成字符串数组见 lib/hooks/security/index.js。完整的取值约束是要么是*要么是字符串数组否则启动时报E_INVALID_SECURITY_CONFIG。allRoutes是否默认对所有路由开启 CORS。默认false即默认阻断所有跨域请求。allowCredentials是否允许携带凭证cookie、Authorization 头等。默认false。源码中有严格的组合校验allowOrigins *与allowCredentials true不能同时出现除非显式开启allowAnyOriginWithCredentialsUnsafe见 lib/hooks/security/index.js该限制用于防止第三方站点诱导已登录用户向你的应用发起未授权请求。allowRequestMethods预检preflight请求允许的 HTTP 方法列表默认覆盖GET, HEAD, PUT, PATCH, POST, DELETE。allowRequestHeaders允许的请求头默认仅content-type。allowResponseHeaders允许暴露给前端 JS 的响应头默认空。allowAnyOriginWithCredentialsUnsafe非安全开关。开启后允许allowOrigins: *与allowCredentials: true同时生效此时 set-headers.js 会把origin置为true改为“反射reflect”请求头中的Origin值作为Access-Control-Allow-Origin而非简单地返回*。仅在你能承受相应风险时使用。csrf全局是否启用 CSRF 防护默认false关闭。这些默认值对应的完整参考文档为 docs/reference/sails.config/sails.config.security.md更通俗的概念说明见 docs/concepts/Security/CORS.md 与 docs/concepts/Security/CSRF.md。CORS 实现原理shadow routes 的绑定CORS 的初始化逻辑在 lib/hooks/security/cors/index.js 中实现核心机制是监听router:before事件抢在显式路由绑定之前挂载 CORS 相关的路由与中间件。整个流程分为四步第一步绑定全局 CORS 处理路由。当sails.config.security.cors.allRoutes true时为/*绑定setHeaders(sails.config.security.cors)中间件类型标记为CORS HOOK: sendHeaders否则默认绑定setHeaders({allowOrigins: false})类型标记为CORS HOOK: clearHeaders即默认阻断所有跨域请求见 lib/hooks/security/cors/index.js。第二步遍历显式路由收集各路由的 CORS 配置。对sails.router.explicitRoutes中的每一条路由按routeConfig.cors的值分四种情况处理见 lib/hooks/security/cors/index.jscors true使用全局默认 CORS 配置为该路由设置响应头cors false为该路由绑定“清除头”中间件使跨域请求拿不到 CORS 头cors为字符串将该字符串作为单一允许来源与全局配置合并后设置响应头cors为对象以该对象为准与全局配置合并设置响应头支持对单个路由做精细化覆盖。第三步绑定预检preflight路由。将收集到的optionsRouteConfigs路径 → 方法 → CORS 配置的映射传给setPreflightConfig为options /*绑定预检处理路由lib/hooks/security/cors/index.js。setPreflightConfiglib/hooks/security/cors/set-preflight-config.js返回一个运行时函数浏览器发起 OPTIONS 预检请求时它根据请求路径与Access-Control-Request-Method请求头通过path-to-regexp匹配对应的路由 CORS 配置若未匹配到任何配置则返回{ allowOrigins: false }等价于不发送Access-Control-Allow-Origin头。第四步真正下发响应头。lib/hooks/security/cors/set-headers.js 是对 Express 4 CORS 模块的修改版。原模块存在“头泄漏”问题——即使请求来源不在白名单中也会设置Access-Control-Allow-Origin、Access-Control-Allow-Methods等头让攻击者嗅探到服务器“本会允许”什么。本仓库版本仅在请求的Origin命中白名单时才发送 CORS 头见 lib/hooks/security/cors/set-headers.js 与isOriginAllowed判断逻辑。同时该模块支持命中白名单时反射Origin值并附加Vary: Origin便于代理正确缓存、设置Access-Control-Allow-Methods、Access-Control-Allow-Credentials、Access-Control-Allow-Headers、Access-Control-Max-Age、Access-Control-Expose-Headers等头对 OPTIONS 预检请求默认以200状态码结束响应optionsSuccessStatus默认 200与 Express CORS 模块默认的 204 不同。全局 CORS 配置实战在项目config/security.js模板见 docs/anatomy/config/security.js.md中开启对所有路由的跨域支持module.exports.security { cors: { allRoutes: true, allowOrigins: [http://example.com, https://api.example.com, http://blog.example.com:1337], allowCredentials: false } };若希望任意域都可访问公开 API 场景module.exports.security { cors: { allRoutes: true, allowOrigins: *, allowCredentials: false // 与 * 组合时强制为 false } };注意来源字符串的书写规范由 lib/util/check-origin-url.js 校验必须以http://或https://开头、不得携带路径/查询串/URL 片段、不得有尾随斜杠、https://不得显式写:443、http://不得显式写:80否则启动时抛出E_INVALID_SECURITY_CONFIG。按路由覆盖 CORS 配置在config/routes.js模板见 docs/anatomy/config/routes.js.md中可对单条路由精确控制module.exports.routes { // 全局开了 allRoutes: true但这条路由豁免跨域 POST /signup: { action: user/signup, cors: false }, // 单路由启用 CORS 并覆盖来源 GET /videos: { action: video/find, cors: { allowOrigins: [https://api.example.com], allowCredentials: false } }, // 简写形式cors 为字符串时视为单一允许来源 GET /public: { action: content/find, cors: https://public.example.com } };在 lib/hooks/security/index.js 的configure阶段会预先遍历sails.config.routes对每条带cors对象的路由执行同样的校验如allowOrigins必须是*或数组、数组元素格式校验、*与allowCredentials: true组合检查发现问题会在启动期直接抛错而不是等到请求时才暴露。CSRF 实现原理白名单/黑名单机制与令牌发放动作CSRF 的初始化逻辑在 lib/hooks/security/csrf/index.js 中实现底层复用了sailshq/csurf中间件实现 OWASP 推荐的 Synchronizer Token Pattern即同步器令牌模式。其核心设计是全局开关 路由级黑白名单构建期router:after遍历sails.router.getSortedRouteAddresses()得到排序后的路由地址对每条显式设置了csrf: true或csrf: false的路由忽略 GET、HEAD、OPTIONS 路由CSRF 防护不适用于这三类方法并打印 debug 日志若全局security.csrf true而某路由csrf: false将该路由方法 正则加入黑名单blacklist若全局security.csrf false而某路由csrf: true将该路由加入白名单whitelist。运行期router:before先为所有请求绑定一个中间件把res.locals._csrf清空随后绑定核心校验中间件全局开启时若请求路径命中黑名单中的任一正则则跳过校验全局关闭时若请求未命中白名单中的任一正则则直接放行命中校验范围后若req.session不存在开发环境下抛出明确的Route ... has CSRF enabled, but the session is disabled!错误生产环境则直接返回403 CSRF mismatch通过csrfMiddleware校验令牌校验失败EBADCSRFTOKEN返回403 CSRF mismatch校验通过且非 socket 请求时将req.csrfToken()写入res.locals._csrf供视图使用。grant-csrf-token 动作lib/hooks/security/csrf/grant-csrf-token.js 定义了令牌发放动作拒绝 socket 请求因为从安全角度将 socket 视为本质上不可信socket 只能“消费”令牌、不能“领取”令牌。生产环境返回404开发环境返回400并提示改用 HTTP(XHR) 请求正常请求返回 JSON{ _csrf: token }。该动作在initialize阶段通过sails.registerAction(grantCsrfToken, security/grant-csrf-token)注册lib/hooks/security/index.js应用侧只需在config/routes.js中挂一条路由即可暴露端点。相关的集成测试位于 test/integration/hook.csrf.test.js可用来验证令牌发放与校验的完整行为。启用 CSRF 防护在config/security.js中开启全局防护module.exports.security { csrf: true };前提必须启用 session 钩子sails.config.session可用否则启动会直接报E_INVALID_SECURITY_CONFIG。开启后所有 POST、PUT、DELETE 请求包括Socket.io 的虚拟请求都必须携带有效的 CSRF 令牌否则返回403。令牌可以通过_csrf参数或X-CSRF-Token请求头两种方式提交!-- 传统表单以隐藏域提交 -- form action/signup methodPOST input typetext nameemailaddress/ input typehidden name_csrf value% _csrf %/ input typesubmit/ /form// AJAX 请求以参数提交 $.post(/checkout, { order: 8abfe13491afe, _csrf: USER_CSRF_TOKEN }); // 或通过请求头提交 $.ajax({ url: /checkout, method: POST, headers: { X-CSRF-Token: USER_CSRF_TOKEN } });单页应用SPA场景下先挂载令牌发放端点再动态获取令牌module.exports.routes { GET /csrfToken: { action: security/grant-csrf-token } };随后GET /csrfToken返回{ _csrf: ajg4JD(JGdajhLJALHDa }前端将其随后续请求提交即可。视图驱动的传统多页应用则可直接用视图局部变量% _csrf %该值由 CSRF 中间件写入res.locals._csrf。若以multipart/form-data上传文件务必把_csrf隐藏域放在file输入框之前否则可能在上传完成前触发超时与 403。按路由豁免或强制 CSRF全局开启后可在config/routes.js中对特定路由豁免module.exports.routes { POST /hooks/some-webhook: { action: webhooks/notify, csrf: false } };反之全局关闭时也可对特定路由单独强制开启csrf: true。从源码看逐路由的csrf设置支持正则路由r|pattern|flags形式会转换为RegExp参与黑白名单匹配。configure 阶段的配置校验与旧版兼容configure函数lib/hooks/security/index.js除了设置默认值还承担两类工作旧配置项自动迁移打 debug 日志并转换sails.config.csrf→sails.config.security.csrfsails.config.cors→sails.config.security.corscors.origin→cors.allowOriginscors.credentials→cors.allowCredentialscors.headers→cors.allowRequestHeaderscors.methods→cors.allowRequestMethodscors.exposeHeaders→cors.allowResponseHeaders路由级配置同样迁移字符串形式的allowOrigins除*外自动按逗号拆分并 trim 为数组非法配置直接抛错E_INVALID_SECURITY_CONFIG等security.csrf true但 session 钩子未启用仍在使用 Sails v1.0 已移除的csrf.routesDisabled应改为逐路由csrf: false仍在使用csrf.origin应将 CORS 配置直接作用于security/grant-csrf-token所在路由仍在使用csrf.grantTokenViaAjax应改为在config/routes.js挂载security/grant-csrf-token动作仍在使用cors.securityLevel保护 socket 请求应改用sails.config.sockets.onlyAllowOriginsallowOrigins既非*也非字符串数组allowOrigins: *与allowCredentials: true同时出现且未开启allowAnyOriginWithCredentialsUnsafeallowOrigins数组中的来源 URL 格式非法。这些启动期校验保证了配置问题在应用拉起时即刻暴露而不是在线上请求中才被发现。事件Eventshook:security:loaded当该钩子被 Sails 核心自动加载并且其initialize函数中的回调已触发时会发出hook:security:loaded事件。其他钩子或应用代码可以通过监听该事件在 CORS 中间件与 CSRF 中间件全部就绪后执行依赖安全能力的初始化逻辑。事件与钩子生命周期的通用说明见 lib/hooks/README.md 与 docs/concepts/extending-sails/Hooks/Hooks.md。小结关注点结论职责绑定 CORS shadow routes 注册security/grant-csrf-token动作隐式默认CORS 默认关闭allRoutes: false、allowOrigins: *、allowCredentials: falseCSRF 默认关闭加载前置moduleloader、userconfigCSRF 开启时还需 session 钩子关键文件lib/hooks/security/index.js、lib/hooks/security/cors/index.js、lib/hooks/security/cors/set-headers.js、lib/hooks/security/csrf/index.js、lib/hooks/security/csrf/grant-csrf-token.js实战入口docs/anatomy/config/security.js.md、docs/anatomy/config/routes.js.md延伸阅读docs/concepts/Security/CORS.md、docs/concepts/Security/CSRF.md、docs/reference/sails.config/sails.config.security.md理解 security 钩子的隐式默认与校验逻辑后你可以在项目启动阶段就把 CORS 白名单、凭证策略与 CSRF 防护一次性配置到位公开 API 用allRoutes: true 白名单/*内部接口按路由用cors: false豁免需要防护的写操作开启csrf: true并针对 Webhook 等外部回调路由以csrf: false定向放行。若仍有未覆盖的问题欢迎向本仓库提交 PR把疑问补充进 lib/hooks/security/README.md 的 FAQ 章节。赞分享后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载相关推荐FEDformer的5个关键应用场景电力负荷预测、气象预报、金融时序分析等FEDformer的5个关键应用场景电力负荷预测、气象预报、金融时序分析等 FEDformer是一款基于深度学习的时序预测模型通过先进的傅里叶增强分解技术后端Sails HTTP 核心钩子Core Hook深入解析HTTP 服务器启动、中间件栈绑定与配置Sails HTTP 核心钩子Core Hook深入解析HTTP 服务器启动、中间件栈绑定与配置 Sails 是一个面向 Node.js 的实时Real后端Sails 安全配置完全指南config/security.js 中的 CORS 与 CSRF 实战解析Sails 安全配置完全指南config/security.js 中的 CORS 与 CSRF 实战解析 config/security.js 是 Sails后端上一篇Blade框架生态扩展10个必备第三方库与插件完整指南下一篇Android TV应用的单元测试覆盖率工具Jacoco集成创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考