前后端分离架构把会话管理、权限校验、数据出口全部打散到了不同端,传统单体应用里靠服务端渲染时顺手做的安全控制基本失效。多数团队把精力放在接口调通和联调上,安全措施往往变成最后补的几行拦截器,这种状态下面临的不是单点漏洞,而是整条链路缺乏统一设防。要搭建整体安全防护体系,必须先承认一个事实:前端不可信,后端不能只做业务校验,网关层必须承担身份与风险的集中决策。
先解决令牌在前后端分离下的真实落地问题
JWT不是默认安全的,很多系统直接把用户ID、角色塞进payload,服务端只验签名不查状态,导致注销、踢人、改密后旧令牌依然可用。整体防护的第一步是建立令牌生命周期管理。登录成功后签发两个令牌:有效期15分钟以内的访问令牌,以及仅在刷新接口使用的长时刷新令牌。访问令牌只放最小必要信息,比如用户标识和令牌唯一编号,角色权限实时从缓存或数据库读取,不要全量塞进JWT。
刷新令牌必须绑定设备指纹和IP变化阈值。用户每次用刷新令牌换新访问令牌时,后端校验该刷新令牌是否已被轮换、是否属于当前用户、是否在允许的时间窗口内。一旦检测到已失效的刷新令牌被再次使用,立即吊销该用户全部会话。这个机制能有效对抗令牌泄露后的重放攻击,比单纯设置长过期时间可靠得多。
网关层做统一身份决策和风险拦截
前后端分离后,前端调用的是大量REST接口,不可能在每个服务里重复写完整的安全逻辑。网关需要承担三项硬职责:验签、鉴权、限流。验签不只是验证JWT格式,还要检查令牌类型,访问业务接口时如果收到刷新令牌,直接拒绝。鉴权阶段从缓存拉取用户权限集合,与接口所需权限做匹配,避免每次都查数据库造成性能瓶颈。
限流策略要区分用户级和IP级。登录、注册、发送验证码、刷新令牌这四个接口必须做严格频控,同一账号连续失败5次锁定15分钟,同一IP每分钟请求超过阈值触发验证码或临时封禁。业务查询接口可以放宽,但需要按用户维度做速率限制,防止单个合法用户把后端拖垮。网关层的限流数据最好放在Redis里,方便多节点共享计数。
前端安全不能只靠藏代码
前端代码完全暴露在浏览器里,任何写在JavaScript里的密钥、接口地址、判断逻辑都可以被逆向。前端安全的核心目标不是保密,而是提高攻击成本、减少可利用的敏感信息。构建时要做代码混淆和压缩,移除sourcemap上传,生产环境禁止开启调试接口。接口请求统一封装,自动携带CSRF防护头,所有敏感操作必须二次确认。
更关键的是前端路由权限控制。菜单隐藏不等于安全,但能减少低水平攻击者的尝试路径。按钮级权限要由前端根据后端下发的权限码控制显示,真正拦截必须依赖后端接口校验。前端存储令牌时优先使用内存变量,刷新令牌放在HttpOnly、Secure、SameSite=Strict的Cookie里,访问令牌如果必须存localStorage,要明确接受XSS泄露的风险,并配合内容安全策略降低注入概率。
接口层必须做输入输出的双向过滤
后端接口接收的参数不能信任任何来源,包括前端提交的JSON、URL参数、Header字段。统一封装参数校验组件,对字符串长度、数值范围、枚举合法性做白名单校验。SQL查询全部走参数化或ORM,禁止拼接。涉及文件上传的接口,校验文件头、大小、扩展名,存储时重命名,读取时限制路径穿越。
输出过滤同样重要。前后端分离接口返回JSON,如果直接把用户输入的内容原样返回,前端渲染时可能触发存储型XSS。后端在输出前对富文本内容做白名单标签过滤,普通文本做HTML实体编码。接口响应头统一加上X-Content-Type-Options: nosniff、X-Frame-Options: DENY、Referrer-Policy: strict-origin-when-cross-origin。这些头虽然不能解决所有问题,但能堵住一批低成本的利用方式。
CORS配置要精确到业务域名
前后端分离必然涉及跨域,很多团队图省事直接配置Access-Control-Allow-Origin: *,等于把接口暴露给任何网站发起的请求。正确做法是维护一份允许来源白名单,根据请求的Origin头动态匹配,匹配成功才返回对应的允许来源。允许的请求方法只开放业务实际使用的GET、POST、PUT、DELETE,允许的请求头明确列出Authorization、Content-Type等必要字段。
对于携带凭证的跨域请求,Access-Control-Allow-Credentials必须为true,且不能与通配符来源同时使用。预检请求的缓存时间控制在合理范围,避免频繁预检影响性能,同时保证策略变更能及时生效。如果业务存在多个子域名,可以考虑在网关层统一处理CORS,避免每个服务单独配置导致遗漏。
敏感数据与日志脱敏必须同步设计
接口返回的用户手机号、身份证号、银行卡号等敏感字段,后端在序列化时统一做掩码处理,前端只展示部分信息。日志系统最容易成为泄露源,打印请求参数时要把密码、令牌、验证码、身份证号等字段替换为占位符。可以自定义日志脱敏注解,在序列化阶段对标记字段做处理,避免开发人员手动遗漏。
数据库存储层面,密码必须使用bcrypt或argon2等慢哈希算法,禁止MD5、SHA1。支付信息、证件信息等核心数据建议使用应用层加密后再入库,密钥通过密钥管理服务托管,不要硬编码在配置文件里。备份数据同样需要加密,防止备份文件泄露导致全量数据裸奔。
安全审计与异常行为检测要形成闭环
整体防护体系不是一次性搭建完就结束,需要持续记录和响应。网关层记录每次请求的用户标识、IP、接口路径、响应状态、耗时,登录日志单独记录成功失败、设备信息、地理位置。基于这些日志可以建立简单的异常检测规则:同一账号短时间内从多个地理位置登录、大量404请求、非工作时间的高频操作、权限变更后的异常访问模式。
检测到异常后要有自动化响应动作,比如强制下线、冻结账号、触发二次验证。安全事件需要通知到管理员,并保留完整的审计轨迹。定期复盘日志中的攻击尝试,把新的攻击特征补充到网关拦截规则里,形成从检测到响应的闭环。
依赖与运行环境的安全基线
前后端分离项目依赖大量第三方包,前端npm包和后端依赖库都可能引入已知漏洞。CI流程中集成依赖漏洞扫描,构建时发现高危漏洞直接中断。运行时容器使用最小基础镜像,以非root用户运行,开启只读文件系统。后端服务的端口不直接暴露公网,全部通过网关转发,服务间通信使用内网域名并启用mTLS。
HTTPS配置不能只停留在有证书,需要禁用过时的TLS版本和弱加密套件,开启HSTS头强制浏览器走加密连接。证书到期监控要自动化,避免过期导致服务中断。密钥轮换策略同样重要,JWT签名密钥、加密密钥定期更换,更换时考虑旧令牌的平滑过渡。
整体安全防护体系的搭建顺序建议从身份认证和网关层开始,这两块是前后端分离架构下风险最集中的地方。然后逐步完善接口校验、前端加固、数据脱敏和审计。每一步都要有明确的校验标准和测试用例,安全措施上线后通过自动化扫描和人工渗透验证有效性。安全不是某个组件的责任,而是贯穿开发、部署、运维全流程的基线要求。
