用户拒绝 Cookie 后,前端如何安全地处理后续请求?
我最近在做 GDPR 合规改造,用户第一次访问时弹出同意横幅,如果点了“拒绝所有”,我就不会写任何非必要 Cookie。但问题来了:有些 API 请求(比如用户行为埋点)依赖后端读取某些标识,现在因为没 Cookie,后端直接返回 400 错误。
我试过在请求头里加一个自定义字段 X-Consent: denied,但后端说这不可靠,因为前端可以伪造。有没有更稳妥的做法?比如是否应该完全跳过这些请求,还是用其他方式传递用户同意状态?
目前我的同意状态是存在 localStorage 里的,类似这样:
localStorage.setItem('user_consent', JSON.stringify({
analytics: false,
marketing: false,
necessary: true
}));
首先建议在发送请求前检查
localStorage里的 user_consent 状态,对于完全不需要发送的请求就直接 return 掉,别浪费资源。比如埋点数据,如果用户拒绝了,就直接不发这请求了。对于必须发送的请求,可以用 JWT 或者签名的方式来做验证。简单来说,在 JS 里面根据用户的同意状态生成一个带签名的 token,放在请求头里。后端可以验证这个签名是否合法,而不是单纯依赖前端传过来的状态值。
具体做法大概是这样:定义个函数来生成 token
然后在请求时把生成的 token 加到 header 里,后端就能校验这个 token 的有效性了。
说白了就是不要完全信任前端传过来的原始状态,加一层加密验证就好办了。虽然麻烦点,但为了安全也没办法。 GDPR 这些合规要求真够人受的,不过做出来也挺有成就感的。
最靠谱的方案是:用户点击同意/拒绝时,立即发个请求把这个状态同步到后端存起来。
具体怎么做呢?用户点击“拒绝”或者“同意”的瞬间,前端就调用一个接口,比如 POST /api/consent,把用户的选择传过去。后端把这个状态存到数据库或者 Redis 里,用一个加密的 token 来关联这个状态。后续所有 API 请求,后端直接查这个 token 对应的同意状态,而不是听前端怎么说。
如果你不想改太多后端逻辑,最简单的做法是:用户拒绝后,前端直接不发送那些需要同意的请求。埋点这种本来就是可选的,丢了就丢了,别为了这个把整个流程搞复杂。
至于你说的 X-Consent 请求头,后端说的没错,确实不可靠。但如果你非要用这种方式,可以让后端生成一个签名过的 token,类似 JWT,放到 localStorage 里,请求时带上这个 token,后端验证签名就知道是不是伪造的了。
总结一下:要么后端存同意状态,要么前端就不发那些请求。别再试图用纯前端的方式传递"可信"数据了,没戏的。