设置"X-CSRF-Token"
值为的COOKIE form_authenticity_token
。
之后,我可以使用以下代码在SPA(单页应用程序)中读取此COOKIE:
当我使用此行时:
var token = document.getElementsByName('csrf-token')[0].content;
它之所以有效,是因为它读取了Rails在html页面中插入的内容:
<%= csrf_meta_tags %>
因此,“ csrf令牌”的内容有效,并且我的Rails应用程序可以验证CSRF。
这是来自Rails的代码:https : //github.com/rails/rails/blob/v5.2.0/actionpack/lib/action_controller/metal/request_forgery_protection.rb
相反,当我使用此行:
const token = readCOOKIE("X-CSRF-Token");
它不起作用,我得到这个错误:
Started POST "/api/v1" for 172.18.0.1 at 2018-05-01 18:52:56 +0000
Processing by MyController#action as */*
Parameters: {"body"=>{}}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
另外,如果我在具有相同脚本的其他服务器(npm http-server或Microsoft IIS或其他服务器)上使用另一个页面,则问题是相同的。
如果我从Rails html页面复制“ csrf-token”的内容并在我的Javascript脚本中使用此行:
const token = "VXaKlO+/Gr/8pGhr5y0bThQ5L/0IDiznMR/9SpaoI6vOoF9KtmB5/9ka+Hz+zjyssNRi/Em/Ye27C+E5pl3odg==";
有用!
所以我的问题是:为什么?
我读过什么(什么都没有!):
https://github.com/equivalent/scrapbook2/blob/master/archive/blogs/2017-10-12-csrf-protection-on-single-page-app-api.md
无效的Auth令牌与Rails,Graphql,Apollo客户端
https://www.bhalash.com/archives/13544808782
Rails CSRF Protection + Angular.js:protect_from_forgery让我注销POST
https://technpol.wordpress.com/2014/04/17/rails4-angularjs-csrf-and-devise/
使用真实性令牌吗?还是禁用它?
在不禁用CSRF保护的情况下进行Rails API设计
小智..
6
Tnx,我让您的代码正常工作。我只需要添加decodeURIComponent()
const token = decodeURIComponent(readCOOKIE("X-CSRF-Token"));
我将这种方法用于带有缓存html的渐进式Web应用程序。默认的rails元标记(<%= csrf_meta_tags %>
)与缓存的html不兼容。
该博客文章还提供了其他一些替代方法:https : //www.fastly.com/blog/caching-uncacheable-csrf-security
1> 小智..:
Tnx,我让您的代码正常工作。我只需要添加decodeURIComponent()
const token = decodeURIComponent(readCOOKIE("X-CSRF-Token"));
我将这种方法用于带有缓存html的渐进式Web应用程序。默认的rails元标记(<%= csrf_meta_tags %>
)与缓存的html不兼容。
该博客文章还提供了其他一些替代方法:https : //www.fastly.com/blog/caching-uncacheable-csrf-security
2> 小智..:
Rails期望的标题名称是X_CSRF_TOKEN
(请注意下划线)。我看不到您共享的其余代码的问题-也许COOKIE中的令牌必须经过URI解码(decodeURIComponent
),所以也没有问题,因此,如果仍然收到警告,请也进行检查。