我不会谈论您必须遵循的特定解决方案,因为有很多,我将讨论主要思想,您可以根据需要实施它。
防止 XSRF 的关键思想是将随机令牌存储在其他域的代码无法访问的地方(例如 cookie)。您可以在服务器端生成此令牌并指示浏览器在整个会话中将其存储在本地。(不需要在服务器端保留任何东西)
每当您执行请求时,发送:
- 您存储中的令牌(如果您使用 cookie,浏览器将自动发送它)。
- 与您的请求中存储的令牌相同(无论是作为标题还是在正文中使用隐藏字段,具体取决于服务器代码获取它的方式)
在服务器端,服务器将检查匹配。
jquery 中的示例代码(带有 jquery cookie 插件):
$.ajax({
url:"someurl",
data:{token:$.cookie('token')}
});
读取cookie的能力证明这是来自你的域,而不是外部域
实现这个机制的方法有很多种(不需要拘泥于特定的方案),只要他们坚持主旨即可:
- 将秘密令牌存储在来自其他域的位置代码中的浏览器中无法读取它。
- 将秘密令牌和相同的令牌从浏览器发送到您的服务器。发送相同令牌的能力证明这不是 XSRF 请求。
我如何保持这个值以便用于比较?
我们可以将其存储为 cookie 或会话变量。就个人而言,我更喜欢 cookie,因为:
- 减少服务器端的内存消耗。
- 我们不需要在每个生成的 HTML 文件中都包含该令牌,以便浏览器将其发回。
同步表单请求与 AJAX 请求的设置有区别吗?
不,只要您可以通过在 request中发送相同的令牌来证明这不是 XSRF 请求。令牌在哪里(隐藏字段、自定义标题、..)并不重要。对于表单,人们通常将其作为隐藏字段发送。