Devign user 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"=>"[email protected]", "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" =  
'[email protected]' 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", Fri, 08 Nov 2013 14:18:49 UTC
+00:00], ["sign_in_count", 3], ["updated_at", Fri, 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 указывает на home#new, который похож на

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

Сгенерированное html-представление страницы Sign_in выглядит так:

  • метатеги

    <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 в контроллере, он приходит как nil.

По мне, он не подписывается user. Но тогда возникает вопрос: "Почему он обновляет значение last_sign_in_at/sign_in_count в таблице user?"

Ответы

Ответ 1

Не было проблем с разработкой драгоценного камня. Я удалил драгоценный камень "rails-api", и мое приложение начало работать.

Ответ 2

Если токен CSRF неверен, Rails не будет читать или делать какие-либо обновления для сеанса. Он по-прежнему будет выполнять любые другие действия, указанные контроллером, что объясняет, почему вы видите обновление БД, но не входите в систему.

Я замечаю, что аутентификация_token в вашем журнале и на вашей странице не соответствует. Я понимаю, это может быть связано с тем, что вы захватили другой запрос, но вы должны убедиться, что тот, который на странице соответствует таковой в журнале для одного и того же запроса. Я также предполагаю, что вы используете правильный тег в своем представлении, который каждый раз генерирует различный authenticity_token и не просто жестко кодирует ввод HTML.

Вы видите ту же проблему с формами, которые не связаны с разработкой? Если нет, в качестве обходного пути вы можете освободить свое действие от проверки CSRF с помощью следующего кода в вашем контроллере:

protect_from_forgery except: :sign_in

Шансы атаки CSRF против действия вашего знака в действии кажутся мне довольно отдаленными (< -pun).

Кроме того, если это просто с разработкой, я предлагаю вам записать с ними проблему, которую вы уже сделали.

Ответ 3

Я исправил ту же проблему, просто удалив опцию "remote: true" в поле зрения: изменил form_for (model, remote: true) на form_for (model)