ruby-on-rails – 设计用户sign_in给出了CSRF令牌真实性令牌的身份验证错误

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 设计用户sign_in给出了CSRF令牌真实性令牌的身份验证错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。



我正在使用devise(最新版本 – 3.2.0)与rails(最新版本 – 4.0.1)

我正在进行简单的身份验证(没有ajax或api),并得到CSRF真实性令牌的错误.检查下面的POST请求

started POST "/users/sign_in" for 127.0.0.1 at 2013-11-08 19:48:49 +0530
Processing by Devise::SessionsController#create as HTML

 Parameters: {"utf8"=>"✓","authenticity_token"=>"SJnGhXXUXjncnPhCdg3muV2GYCA8CX2LVFV78pqddD4=","user"=> 
{"email"=>"a@a.com","password"=>"[FILTERED]","remember_me"=>"0"},"commit"=>"Sign in"}

Can't verify CSRF token authenticity
 User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."email" =  
'a@a.com' LIMIT 1
(0.1ms)  begin transaction
sql (0.4ms)  UPDATE "users" SET "last_sign_in_at" = ?,"current_sign_in_at" = ?,"sign_in_count" = ?,"updated_at" = ? WHERE "users"."id" = 2  [["last_sign_in_at",Fri,08 Nov 2013 14:13:56 UTC +00:00],["current_sign_in_at",08 Nov 2013 14:18:49 UTC
+00:00],["sign_in_count",3],["updated_at",08 Nov 2013 14:18:49 UTC +00:00]]
(143.6ms)  commit transaction
Redirected to http://localhost:3000/
Completed 302 Found in 239ms (ActiveRecord: 144.5ms | Search: 0.0ms)

根url指向#新的,这就像

class HomeController < ApplicationController
   before_action :authenticate_user!
   def index
   end
end

Sign_in页面生成的html视图就像:

>元标记

<Meta content="authenticity_token" name="csrf-param" />
<Meta content="aV+d7Z55XBJF2VtyL8V3zupR3OwhaQ6UHNtlQLBQf5Y=" name="csrf-token" />

>形式

<form accept-charset="UTF-8" action="/users/sign_in" class="new_user" id="new_user" 
method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="&#x2713;" />
<input name="authenticity_token" type="hidden
value="aV+d7Z55XBJF2VtyL8V3zupR3OwhaQ6UHNtlQLBQf5Y=" />
</div>
<div><label for="user_email">Email</label><br />
<input autofocus="autofocus" id="user_email" name="user[email]" type="email" value="" />
</div>

<div><label for="user_password">Password</label><br />
<input id="user_password" name="user[password]" type="password" /></div>

<div><input name="user[remember_me]" type="hidden" value="0" />
<input id="user_remember_me" name="user[remember_me]" type="checkBox" value="1" /> 
<label for="user_remember_me">Remember me</label></div>

<div><input name="commit" type="submit" value="Sign in" /></div>
</form>

认证请求甚至更新last_sign_in_at和sign_in_count值,但是当我尝试访问控制器中的current_user时,它为零.

根据我的说法,实际上并没有登录用户.但是问题来了“为什么在用户表中更新last_sign_in_at / sign_in_count值?”

解决方法

当CSRF令牌不正确时,Rails将不会读取或对会话进行任何更新.它仍然会执行控制器指定的任何其他操作,这就解释了为什么看到数据库更新,但是最终没有登录.

我注意到您的日志和页面中的authenticity_token不匹配.我知道这可能是因为您捕获了一个不同的请求,但是您应该检查页面上的请求是否与日志中相同的请求匹配.我也假设你在你的视图中使用了正确的标签,它每次生成不同的authenticity_token,而不仅仅是对HTML输入进行硬编码.

你看到与设计无关的表单有同样的问题吗?如果没有,作为解决方法,您可以使用控制器中的以下代码将CSR操作从CSRF检查中免除:

protect_from_forgery except: :sign_in

对您的登录行为的CSRF攻击的几率似乎对我来说非常遥远(< -pun). 另外,如果它只是设计,那么我建议你提出一个问题,他们,which you’ve already done.

猜你在找的Ruby相关文章