为什么要把服务器发送cookie ...
,使服务器能够知道(验证),从你的应用程序中的第二个请求从您的应用程序来精确地(因为相同的应用程序是只有第一个请求的响应的接收者)。我说该令牌不用于授权,因为它直接从令牌映射到的用户派生。例如,您不能使用该令牌来删除其他用户。但是,您的代码仍然可以被利用,并且该令牌会受到恶意代码的危害,但我们稍后再考虑。
...而不是仅仅将其设置在客户端上...
任何事先沟通的设置用于不同的用途,看看https://en.wikipedia.org/wiki/Shared_secret或https://en.wikipedia.org/wiki/Symmetric-key_algorithm。您的应用程序是公开的,它解释了为什么不提前将其设置在客户端上。
使用简单的javascript和生成的随机uuid值?
设置uuid是毫无意义的,因为任何人都可以这样做:您的服务器无法区分uuid与应用程序和黑客的区别。
另外,如果你有一个公共的应用程序,每个人都可以访问,还是需要保护它免受CSRF ...
但是,如果你的应用程序(和其中的API)是公开的,你不应该保护它,对吧?试试curl https://api.github.com/users/mongodb/repos
。我最近了解到,您可以通过提供cookie atl.xsrf.token=no-check
(也可以通过头文件工作,请注意JSESSIONID仍用于实际身份验证)来禁用Bamboo api的XSRF保护。
服务器端如何记住它向什么用户发送的令牌,如果他们没有会话cookie?
XSRF令牌通常会作为自定义X-
HTTP标头进来。甚至作为路径/查询参数,不需要cookie。
XSRF仅用于通过使用您的API向其应用发送最后一个请求(或免费获得新标记的初始GET
)的令牌来验证您的应用的下一个请求。正如其他答案正确指出的那样,服务器可以决定使用每个幂等请求来更改标记。标准做法是对每个请求都有一个新的标记,但它们很便宜。
最后但并非最不重要的,想想一些利用情况:
- 如果我管理注入一些JavaScript,并获得您的应用程序的饼干,其中令牌(或DOM或JS命名空间或通过一些访问令牌js getter),然后我可以验证
DELETE
对您的api的请求
- 如果我设法将您的应用程序重定向到我的服务器(任何欺骗您的DNS,没有SSL等),我得到您的令牌,我的下一个
DELETE
请求可能会被拒绝,如果:
- 您的服务器要求每个请求一个新的令牌,并...
- 你设法比我更快地使之间的要求,我会再试一次或...
- 服务器是足够聪明地看到,用同样的多个请求来自不同IP的,并至少给你喜欢的Gmail
- 警告如果我管理重定向服务器API的响应(意思是我有一个新的令牌),我
DELETE
请求将会成功,但你下一个请求会给你一个警告,说你正在访问一个陈旧的资源(我的请求已被修改)。我认为这是对会议的乐观锁定。
总之,不要为您的公共API使用csrf。在渲染数据时使用它,在你的代码或幂等通话中包含远程资源,但保持良好。希望这一切都有道理。
_“如果服务器端会记住它向哪个用户发送什么令牌(如果他们没有会话cookie的话)?” - - 它首先必须有其他一些标准来识别用户,你觉得呢? – CBroe
以什么方式将CSRF令牌从服务器传递到客户端并返回并不重要。 – CBroe