devise 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"=>"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", 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 выглядит так:
Мета-теги
<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="✓" /> <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
Таблица?"
4 ответа
Там не было никаких проблем с разработкой драгоценного камня. Я удалил драгоценный камень rails-api, и мое приложение начало работать.
Если токен CSRF неверен, Rails не будет читать или обновлять сеанс. Он по-прежнему будет выполнять любые другие действия, указанные контроллером, что объясняет, почему вы видите обновление БД, но не заходите в систему.
Я замечаю, что authenticity_token в вашем журнале и на вашей странице не совпадают. Я понимаю, что это может быть связано с тем, что вы перехватили другой запрос, но вы должны проверить, совпадает ли тот, что на странице, с тем, что в журнале, для того же запроса. Я также предполагаю, что вы используете правильный тег в вашем представлении, который каждый раз генерирует новый authenticity_token, а не просто жестко кодирует ввод HTML.
Вы видите ту же проблему с формами, не связанными с разработкой? Если нет, то в качестве обходного пути вы можете освободить свое действие от проверки CSRF с помощью следующего кода в вашем контроллере:
protect_from_forgery except: :sign_in
Шансы CSRF-атаки на ваш знак в действии кажутся мне довольно далекими (<-pun).
Кроме того, если это просто с разработкой, то я бы предложил вам подать проблему с ними, что вы уже сделали.
Добавьте это на Application Controller (это работает на Rails 5)
protect_from_forgery unless: -> { request.format.json? }
Добавьте это в Devise SessionController
skip_before_action :verify_authenticity_token, only: [:create]
Попробуй с curl
curl -X POST -v -H 'Content-Type: application/json' http://0.0.0.0:3000/users/sign_in -d '{"user" : {"email": "name@mail.com", "password": "secret" }}'
Я исправил ту же проблему, просто удалив опцию "remote: true": изменил form_for(модель, remote: true) на form_for(модель)