前后端分离架构彻底改变了Web应用的开发模式,但将认证、授权、数据传输和逻辑处理完全剥离到客户端后,API就赤裸裸地暴露在公网之上。这意味着攻击面从传统的服务端渲染漏洞,全面转向了API接口本身。直接面对的问题就是:如何确保调用者身份真实、请求未被篡改、权限被精确控制,以及数据在传输和落地时不被窃取。下面直接拆解具体的防护要点和落地方法。

无状态Token的存储与传输陷阱

JWT(JSON Web Token)是分离架构下最主流的认证方案,但绝大多数安全隐患都出在Token的存储和传输环节。前端将JWT存储在localStorage或sessionStorage中,看似方便,却极易遭受XSS攻击。一旦页面注入恶意脚本,攻击者可直接读取Storage中的Token并外传。更安全的做法是将Token存储在HttpOnly、Secure、SameSite属性齐全的Cookie中,由浏览器自动携带,JavaScript无法访问。但这又引入了CSRF风险,因此必须配合SameSite=Lax或Strict,并额外增加自定义请求头校验,比如要求前端在每次请求时从Cookie中读取一个非HttpOnly的CSRF Token,并置于X-CSRF-TOKEN请求头中,服务端进行比对。传输层面,强制全站HTTPS是底线,同时设置Strict-Transport-Security响应头,杜绝任何降级攻击的可能。对于高敏感系统,还应将Access Token的有效期控制在15分钟以内,并配合使用Refresh Token,Refresh Token必须设置为HttpOnly且路径限定在刷新接口,进一步缩小泄露后的影响窗口。

前端路由权限不等于真正的权限控制

很多团队在前端根据用户角色隐藏菜单或按钮,就认为完成了权限控制,这是致命的误解。前端权限仅仅是UI层面的体验优化,真正的权限校验必须在API层完成,且要细化到每一个接口、每一个操作。实现上,应采用RBAC(基于角色的访问控制)或更细粒度的ABAC(基于属性的访问控制)模型。在API网关或中间件层,对每个请求进行拦截,解析Token中的用户身份和角色,与所请求的资源操作进行比对。例如,一个普通用户即便通过浏览器开发者工具拼凑出删除用户的API请求,服务端也必须严格校验其角色是否包含“用户管理-删除”权限,而非信任前端传来的任何标识。更进阶的做法是将权限策略外部化,使用策略引擎动态评估,避免硬编码权限逻辑。同时,API返回的数据也应根据权限进行过滤,比如一个部门主管调用获取员工列表接口,后端应只返回其管辖范围内的数据,而不是把全量数据扔给前端再去过滤。

输入校验的双层防御与序列化安全

前后端分离后,后端接收到的数据格式几乎全是JSON。攻击者可以直接构造恶意JSON载荷,绕过前端的所有校验。因此,后端必须对所有输入字段进行严格的白名单校验,包括数据类型、长度、格式和取值范围。不能依赖前端的正则或必填判断。例如,用户注册接口的邮箱字段,后端必须再次用严格的正则验证格式,并对字符串进行HTML实体编码后再存入数据库,防止存储型XSS。对于数字类型的ID,必须校验是否为纯数字且大于0,防止SQL注入或越权。此外,JSON解析器本身也可能存在反序列化漏洞,应禁止接收超大嵌套深度的JSON,限制请求体大小,并确保使用的JSON库保持最新版本。在响应端,设置Content-Type: application/json,并确保所有输出都经过正确的JSON序列化,避免浏览器进行MIME类型嗅探而触发XSS。

防重放与请求完整性校验

即便请求走HTTPS,攻击者仍可能截获并重放某些关键请求,比如支付、转账或密码修改。防御重放攻击的核心是引入请求唯一性和时效性标识。常用的方案是要求客户端在每个请求中携带一个随机生成的Nonce字符串和一个精确到秒的时间戳,服务端在合理时间窗口内(如60秒)检查该Nonce是否已被使用过,并缓存在Redis中。对于特别敏感的操作,还可以要求客户端对请求体进行摘要签名。例如,将请求参数按字典序排序后拼接,再使用共享密钥生成HMAC-SHA256签名,置于请求头中。服务端以同样方式计算签名并比对,任何参数被篡改都会导致签名不匹配。这不仅能防重放,还能确保请求内容在传输过程中未被中间人修改。

API限流与异常流量识别

公开的API接口极易被恶意爬虫、撞库或DDoS攻击。限流策略需要分层设计:在API网关层,基于IP地址和用户ID进行双重限流。对于未认证的接口(如登录、注册),严格限制单IP的请求频率,比如每分钟不超过10次,超过则触发验证码或临时封禁。对于已认证接口,基于用户ID进行限流,防止单个账户高频调用拖垮系统。更精细的做法是引入令牌桶或漏桶算法,允许一定的突发流量,但保持后端服务的稳定。此外,还应部署异常流量分析系统,监控请求模式,比如同一IP在短时间内尝试大量不同用户名登录,或请求时间间隔呈现明显的脚本特征,这类流量应立即触发告警并自动拉黑。

CORS配置的精确化

跨域资源共享(CORS)是分离架构的必然需求,但Access-Control-Allow-Origin绝不能设置为*。这等于允许任何恶意网站通过用户的浏览器携带凭证访问API。正确的做法是严格配置允许的源域名白名单,并根据请求动态匹配。如果业务需要支持多个合法域名,服务端应读取请求头中的Origin,在白名单中查找并原样返回,而不是简单反射。对于携带凭证的请求,Access-Control-Allow-Credentials设置为true时,Access-Control-Allow-Origin必须指定具体域名,不能为*。同时,Access-Control-Allow-Methods应仅列出业务实际使用的HTTP方法,Access-Control-Allow-Headers也应限制为必要的请求头,避免过度开放。

敏感数据的传输与存储加密

密码、身份证号、银行卡号等敏感数据,在传输层已有TLS保护,但应用层仍需额外加固。对于密码,前端应在提交前使用慢哈希算法(如bcrypt或scrypt)进行预哈希,服务端接收到后再次进行哈希加盐存储。这样即使HTTPS在极端情况下被解密,攻击者拿到的也只是哈希值而非明文。对于需要在服务端解密使用的敏感数据(如支付卡号),应采用信封加密模式:使用对称密钥加密数据,再用非对称密钥加密对称密钥。API响应中返回给前端的敏感字段,应根据业务需要进行脱敏处理,比如手机号显示为1381234。日志系统中,必须建立敏感数据过滤机制,禁止将请求体或响应体中的密码、Token、身份证号等完整记录。

API版本管理与废弃接口的及时下线

随着业务迭代,旧版本API如果长期存在且维护缺失,会成为系统的薄弱环节。每个API版本都应设定明确的生命周期,并在响应头中通过Deprecation和Sunset字段告知客户端下线时间。前端应用应始终请求明确的API版本号路径(如/v1/、/v2/),而不是依赖默认版本。服务端对已废弃的接口,应在过渡期结束后直接关闭,而不是保留空实现或返回模糊的错误信息。定期进行API资产盘点,扫描并关闭那些不再被任何前端调用的僵尸接口,是降低攻击面的有效手段。

日志审计与实时威胁响应

API安全的最后一道防线是完整的日志记录和实时监控。每条日志应包含请求时间、来源IP、用户ID、请求方法、URL、响应状态码和处理耗时。对于认证失败、权限拒绝、参数校验失败等事件,应记录详细原因,并触发实时告警。建立基于规则的实时分析引擎,当检测到同一用户短时间内出现大量403错误,或某个IP频繁触发限流,系统应自动提升该主体的风险等级,并可联动WAF或网关进行临时封禁。日志本身的安全也需要重视,集中存储的日志系统应实施严格的访问控制,并确保日志不被篡改或删除。