早在2011年2月,Rails就被修改为对所有非GET请求,甚至是API端点的请求,都需要CSRF令牌。我理解为什么这是对浏览器请求的一个重要更改的解释,但是那篇博文没有提供任何关于API应该如何处理更改的建议
我对某些操作禁用CSRF保护不感兴趣
API应该如何处理这种变化?是否期望API客户端向API发出GET请求以获取CSRF令牌,然后在会话期间将该令牌包含在每个请求中
令牌似乎不会从一篇文章更改为另一篇文章。假设令牌在会话期间不会更改是否安全
我不喜欢在会话过期时进行额外的错误处理,但我认为这比在每次POST/PUT/DELETE请求之前都必须获得令牌要好
这是一个老问题,但安全性非常重要,我觉得它应该得到一个完整的答案。正如本问题中所讨论的,即使使用API,CSRF仍然存在一些风险。是的,默认情况下浏览器应该防止这种情况发生,但由于您无法完全控制用户安装的浏览器和插件,因此在API中防止CSRF仍然是一种最佳做法
有时我看到的方法是从HTML页面本身解析CSRF元标记。但我并不喜欢这种方式,因为它不适合当今许多单页+API应用程序的工作方式,我觉得无论是HTML、JSON还是XML,都应该在每个请求中发送CSRF令牌
因此,我建议改为通过after过滤器将CSRF令牌作为cookie或头值传递给所有请求。API可以简单地将其重新提交为Rails已经检查过的X-CSRF-Token头值
这就是我对AngularJS的处理方式:
在我的应用程序控制器中
在\u过滤器之后:设置\u csrf\u cookie
def set_csrf_cookie
如果保护你不被伪造?
cookies[‘XSRF-TOKEN’]=表单\u真实性\u TOKEN
终止
终止
AngularJS会自动查找名为XSRF-TOKEN的cookie,但出于您的目的,您可以随意为其命名。然后,当您提交POST/PUT/DELETE时,您应该设置Rails自动查找的标题属性X-CSRF-Token
不幸的是,AngualrJS已经在X-XSRF-TOKEN的头值中发回XSRF-TOKENcookie。在ApplicationController中,很容易覆盖Rails的默认行为来适应这一点,如下所示:
受保护
def验证请求?
super | | form_authenticity_token==request.headers['X-XSRF-token']
终止
对于Rails 4.2,现在有一个内置的帮助程序来验证应该使用的CSRF
受保护
def验证请求?
超级| |有效的_真实性_令牌?(会话,请求.头文件['X-XSRF-token'])
终止
我希望这会有帮助
编辑:在我提交的Rails pull请求的讨论中,通过API传递CSRF令牌进行登录是一种非常糟糕的做法(例如,有人可以为您的站点创建使用用户凭据而不是令牌的第三方登录)。所以,请注意。这取决于你决定你有多关心你的申请。在这种情况下,您仍然可以使用上述方法,但只能将CSRF cookie发送回已经有经过身份验证的会话的浏览器,而不是针对每个请求。这将阻止在不使用CSRF元标记的情况下提交有效登录