- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 Rails 生产中收到“无法验证 CSRF token 真实性”。我的问题是:
这是我的 Heroku 日志(一些值已匿名):
2016-02-13T01:18:54.118956+00:00 heroku[router]: at=info method=POST path="/login" host=[MYURL] request_id=[ID STRING] fwd="FWDIP" dyno=web.1 connect=0ms service=6ms status=422 bytes=1783
2016-02-13T01:18:54.116581+00:00 app[web.1]: Started POST "/login" for [IPADDRESS] at 2016-02-13 01:18:54 +0000
2016-02-13T01:18:54.119372+00:00 app[web.1]: Completed 422 Unprocessable Entity in 1ms
2016-02-13T01:18:54.118587+00:00 app[web.1]: Processing by SessionsController#create as HTML
2016-02-13T01:18:54.118637+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"[BIGLONGRANDOMTOKENSTRING]", "session"=>{"email"=>"[FRIENDSEMAILADDRESS]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
2016-02-13T01:18:54.119082+00:00 app[web.1]: Can't verify CSRF token authenticity
2016-02-13T01:18:54.120565+00:00 app[web.1]:
2016-02-13T01:18:54.120567+00:00 app[web.1]: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
2016-02-13T01:18:54.120569+00:00 app[web.1]: vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'
.
.
.etc
我所知道的唯一表现是当我的 friend 试图在他的 iPhone 5 上使用 Safari 登录时。他的用户帐户是大约 6 个月前创建的。我 99% 确定他当时用手机可以正常访问该网站。从那以后他就没有登录过,我也不知道我对登录/授权码做了任何更改。昨天我让他在大约 6 个月内第一次访问我的网站,现在他遇到了 CSRF 错误。
此问题不会发生在任何其他用户帐户(据我所知)或任何其他设备上。事实上,从他的旧款 iPhone 4 登录他的帐户就可以了。
我有相当多的开发经验,但对网络开发和 Rails 的一切都是全新的。
这是我所拥有的:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
include SessionsHelper
end
应用布局:
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
</head>
<body>
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>
<%= yield %>
<%= render 'layouts/footer' %>
<%= debug(params) if Rails.env.development? %>
</div>
</body>
</html>
我的 secret 文件如下所示:
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
我在 Heroku 上有一个用于 secret_key_base 的生产环境变量。
def log_in(user)
session[:user_id] = user.id
end
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
这是我所做的:
我按照 Michael Hartl's Rails Tutorial 中的所有内容开始开发我的应用程序直到第 10 章为止/一直到第 10 章。最相关的是第 8 章。具体来说,我的应用程序使用所有安全/cookie/用户身份验证内容,与 tut 中完全一样。我没有在我的应用程序中做任何花哨的事情……没有 AJAX 或类似的东西。我什至猛拉了turbolinks。
我的项目跨越了过去 18 个月,所以我不能 100% 肯定我是从哪个版本开始的。我知道它是 4.1.X,可能是 4.1.6。我也不确定我升级的日期,但在某些时候对我目前正在运行的进行了升级; 4.2.0。
我几乎阅读了我在网上找到的所有关于 CSRF + Rails 问题的帖子。似乎对于我读过的几乎所有内容,原因和解决方案都与 AJAX 或 Devise 有关,但两者都不适用于我。 iFrame 问题是网络上的另一个常见来源,我都没有使用它。
我使用了我的应用程序的密码重置功能但无济于事。我尝试将 protect_from_forgery 更改为 with: :reset_session。唯一的变化是不再显示 Rails 异常页面。但它不会让他转到任何需要身份验证的页面。它只是让他回到根目录,因为我的 route 有这一行:
get '*path' => redirect('/')
我不想清除他的 cookie/缓存等,因为我有许多其他现有用户帐户,我不想手动修复它们。
经常建议的解决方案是关闭安全性的一些变体,出于显而易见的原因我不想这样做。
其他一些我已经更改但还没有机会测试的东西(因为我不能轻松访问我 friend 的 iPhone):
我更改了 session_store.rb 中的应用商店名称:
Rails.application.config.session_store :cookie_store, key: '[NEWNAME]'
运行以下命令:
heroku 运行 rake assets:clean
heroku 运行 rake assets:precompile
我即将开始深潜here ,尤其是第 3 节。
感谢阅读/考虑。任何提示/想法/建议/指针将不胜感激!
最佳答案
结果 this gentleman遇到了与我完全相同的问题,并且能够创建一个对我有用的复制案例。如果我没理解错的话,Safari 会缓存页面,但会破坏 session 。这导致 authenticity_token 值在我的 rails 参数中看起来合法,但 protect_from_forgery 在验证 token 时失败,因为 session 已被破坏。
解决方案有两个:关闭缓存和处理 CSRF 异常。即使您关闭缓存,您仍然需要处理异常,因为某些浏览器(例如 Safari)不遵守无缓存设置。在这种情况下会出现 CSRF 问题,因此也需要处理该问题。
我的解决方法是通过清除我所有的 cookie 和 session 数据来处理 CSRF 异常,闪烁一条“oops”消息并将它们重定向到登录页面。重定向将拉取一个新的身份验证 token ,该 token 将在执行登录后进行验证。这个想法来自here :
It is common to use persistent cookies to store user information, with cookies.permanent for example. In this case, the cookies will not be cleared and the out of the box CSRF protection will not be effective. If you are using a different cookie store than the session for this information, you must handle what to do with it yourself:
rescue_from ActionController::InvalidAuthenticityToken do |exception|
sign_out_user # Example method that will destroy the user cookies
end
The above method can be placed in the ApplicationController and will be called when a CSRF token is not present or is incorrect on a non-GET request.
cookies.permanent 正是我使用的。所以我像这样实现了上面的技巧:
class ApplicationController < ActionController::Base
include SessionsHelper
protect_from_forgery with: :exception
before_filter :set_cache_headers
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies.delete(:user_id)
cookies.delete(:remember_token)
session.delete(:user_id)
@current_user = nil
flash[:danger] = "Oops, you got logged out. If this keeps happening please contact us. Thank you!"
redirect_to login_path
end
def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
end
顺便说一句,在实现修复并验证它在开发中工作后,我 friend 的手机仍然无法登录,尽管行为有所不同。经过调查,我发现他在 iPhone 5 Safari 设置中“阻止了所有 cookie”。这导致了其他奇怪的行为,使得很难找出是哪个问题导致了什么。当我意识到我无法使用他的手机登录任何在线帐户(例如雅虎邮箱等)时,就收到了提示。进入他的 Safari 设置并允许 cookie 解决了问题,现在他的手机(以及我所知道的其他任何地方)一切正常。
关于html - 为什么 Rails 给我 "Can' t verify CSRF token authenticity”错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35417479/
假设我的 Web 应用程序使用 CSRF token 防止 CSRF 攻击,此外,它使用 SSL 并防止 XSS 攻击。此外,出于这个问题的目的,假设它仅在最近的浏览器中使用并且它们没有错误。我可以使
很多人都在谈论实现 CSRF 来阻止对网页的跨站点攻击。但我认为破坏 CSRF 并向服务器发出请求非常容易。 那么它是如何工作的呢? 您从一个页面开始,呈现一个表单并使用 CSRF token 保留一
在阅读了许多有关 CSRF 的文档后,我仍然有点困惑。所以我希望有人可以向我解释一下: 假设我有一个仅供经过身份验证的用户使用的个人资料页面,比如说 abc.com/profile,它会显示我所有的私
我们基于 Angular 的 web 应用程序与在不同域和上下文路径上运行的企业门户集成。我正在使用基于 Spring Security 的 CSRF token 来验证传入的请求。该应用程序在本地完
我正在开发一个 Web API。身份验证是通过 cookie 进行的。所有端点通过JSON接收参数在请求正文中。 我需要实现 CSRF token保护他们?这怎么可能被利用呢?是否可以通过正常发送JS
我正在开发一个从 cookie header 解析 CSRF token 的应用程序。我想知道 CSRF token 是否使用 URL 安全字符进行 base64 编码(参见 https://simp
我知道当提交时表单中未包含 csrf token 时会发生此错误,但这次并非如此。 我正在尝试登录管理站点。管理员登录表单包含 csrf token ,我可以看到该 csrf token 的值与 cs
有没有办法对 Controller 的某些操作禁用 CSRF 验证,同时对其他操作保持启用状态? 就我而言,我有几个可配置的 Action 类,它们旨在注入(inject)到 Controller 中
我正在编写一个应用程序(Django,确实如此),我只想了解“CSRF token ”实际上是什么以及它如何保护数据。 如果不使用CSRF token ,发布数据不安全吗? 最佳答案 简单来说跨站请求
来自维基百科关于同源政策 https://en.wikipedia.org/wiki/Same-origin_policy The same-origin policy helps protect s
我在 Vue 环境中使用 axios 与用 Symfony 编写的网络服务对话。每个请求都需要设置一个 X-Auth-Token header 。该值存储在 auth_token cookie 中。
我想保护我的 REST 调用免受 XSRF 攻击。我正在做的是: 服务器在用户成功登录后向浏览器发送一个记录的 cookie。 在每个请求(GET、POST、DELETE)上,我将登录的 cookie
我知道这个问题以前有人问过。我已经尝试了人们给出的几乎所有选项,但我似乎无法解决它。我是一个完整的新手,所以请让我知道我哪里出错了。 我正在尝试编写一个简单的原始表单。到目前为止,我还没有实现任何身份
似乎 Laravel 5 默认将 CSRF 过滤器应用于所有非获取请求。这对于表单 POST 是可以的,但对于 POST DELETE 等的 API 可能是一个问题。 简单的问题: 如何设置没有 CS
当我从客户端向服务器发出 DELETE 请求时,我遇到了错误。 “CSRF token 已关联到此客户端”。响应代码:403 和响应头 { "cache-control": "no-cache,
to prevent CSRF attacks, a random CSRF secret has been generated. 以上内容来自 symfony: http://www.symfony
我正在使用 Django Rest Framework还有 django-rest-auth . 我有标准的 API 端点(/login、/logout、/registration...) 使用我的浏
这个问题在这里已经有了答案: OAuth2.0 Server stack how to use state to prevent CSRF? for draft2.0 v20 (3 个回答) 4年前关
我需要知道如何在 Impresspages cms 中禁用 CSRF 功能。我在之前的帖子中看到了一个可能的答案,但没有完全分类。当我的客户在 cleanwaterpartnership.co.uk
我正在使用 Django 1.7 和 django-rest-framework。 我制作了一个 API,它返回一些 JSON 数据并将其放入我的 settings.py REST_FRAMEWORK
我是一名优秀的程序员,十分优秀!