Изобретите надзирателя 401 Неавторизованный, когда неправильные учетные данные

У меня довольно стандартная процедура входа в Devise:

Вид:

resource_name, :url => session_path(resource_name)) do |f| %>
<%= f.input :password, input_html: {class: "span6"} %>

<% if devise_mapping.rememberable? -%>
    <p><%= f.check_box :remember_me %>&nbsp;&nbsp;&nbsp;Remember me</p>
<% end -%>

<input type="hidden" name="after_sign_in_page" value="<%=@after_sign_in_page%>">
<p><%= f.submit "Sign in", class: "btn btn-success" %></p>

И я только что создал контроллер сеанса, чтобы уменьшить адрес электронной почты:

class SessionsController < Devise::SessionsController

  def create
    params[:user][:email].downcase!
    super
    logger.debug "Errors: #{resource.errors}"
  end

Вход в систему с хорошими учетными данными происходит нормально.

С неправильными учетными данными он перенаправляет на страницу входа с этим журналом:

Started POST "/users/sign_in" for 127.0.0.1 at 2013-01-10 09:59:44 +0100
Processing by SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"8eytQkr20JOOOdDvpCWakbmUzNoaHMxK9/BSEVxETik=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "after_sign_in_page"=>"", "commit"=>"Sign in"}
Time zone: (GMT+00:00) UTC, current area: , user to register: , current controller: sessions
Completed 401 Unauthorized in 69ms
Processing by SessionsController#new as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"8eytQkr20JOOOdDvpCWakbmUzNoaHMxK9/BSEVxETik=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "after_sign_in_page"=>"", "commit"=>"Sign in"}
  Rendered devise/sessions/_new.html.erb (17.8ms)
  Rendered devise/sessions/new.html.erb within layouts/application (19.7ms)
  Rendered layouts/_header.html.erb (66.1ms)
Completed 200 OK in 173ms (Views: 98.3ms | ActiveRecord: 0.9ms)

Судя по всему, 401-й сброшен Стражем, но я не мог понять, почему. Пользователь корректно перенаправляется обратно на страницу входа, но сообщение об ошибке не отображается (это нормально, так как они удаляются при перенаправлении)

Что я делаю неправильно?

Благодарность!

РЕДАКТИРОВАТЬ 1:

На данный момент я нашел быстрый хак. Я добавил это в SessionsController#new

if params[:user]
  flash[:alert] = "Incorrect login or password"
end

Не очень элегантно, но, по крайней мере, у меня что-то есть.


person ndemoreau    schedule 10.01.2013    source источник


Ответы (3)


Ваше флеш-сообщение не будет установлено, потому что Devise::SessionsController#create вызывает надзирателя для проверки подлинности, который, в случае неудачи, вызовет Devise::FailureApp. Ваш контроллер никогда не обрабатывает сценарии отказа.

Если вам нужно специальное сообщение, вы можете настроить для него приложение об ошибке, в Devise wiki объясняя, как это сделать.

Но в целом вы можете настроить свои сообщения об ошибках через I18n, и, вероятно, есть лучший способ добиться того, чего вы хотите, без необходимости переопределять контроллеры Devise.

person José Valim    schedule 12.02.2013
comment
Привет Хосе, большое спасибо за вашу помощь! Я не знаю, где вы находите всю эту энергию. После многочасовой борьбы я, наконец, нашел виновного там, где я этого не ожидал: я добавил дополнительную проверку в ApplicationController для сброса сеанса, если current_user был равен нулю, и это, по-видимому, конфликтовало с Devise... Остальная часть конфиг был в порядке... Ааааа! - person ndemoreau; 14.02.2013

Прежде всего, позвольте мне посоветовать вам не переопределять контроллеры Devise:

  1. В этом случае Devise позаботится о преобразовании электронной почты в нижний регистр, поэтому нет необходимости перезаписывать метод create.
  2. Ваше приложение будет без проблем поддерживать обновления Devise, если вы придерживаетесь стандарта.

Кроме того, Devise должен автоматически устанавливать ошибку флэш-памяти, убедитесь, что вы отображаете ее в своем представлении.

Код состояния 401 — это просто стандартный ответ на несанкционированные запросы.

401 Unauthorized похож на 403 Forbidden, но специально для использования, когда требуется аутентификация, которая не удалась или еще не была предоставлена.

http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Вам определенно следует подумать об отказе от своего пользовательского контроллера,

Ваше здоровье

person jassa    schedule 22.01.2013
comment
Возможно, они добавили нижний регистр в последних версиях Devise. Этого не было, когда я добавил этот метод в версию 1.5 или около того. Во всяком случае, я попытался сбросить контроллер, но я все еще не получаю флэш-сообщения. - person ndemoreau; 23.01.2013
comment
Убедитесь, что вы правильно настраиваете свою модель github.com/plataformatec/devise#configuring-models - person jassa; 23.01.2013
comment
Кроме того, флэш-сообщения появились задолго до этого, Devise использует флэш-сообщения с I18n с клавишами флэш-памяти :notice и :alert. github.com/plataformatec/devise#i18n. Убедитесь, что ваше представление указывает на то же действие, что и github.com/plataformatec/devise/blob/master/app/views/devise/. В конце концов, это должна быть проблема с вашим пользовательским кодом, возможно, вы делаете больше, чем показано здесь, обратите особое внимание на дополнительные перенаправления, которые вы выполняете. См. bit.ly/V7larc. - person jassa; 23.01.2013

Я согласен с jassa, просто обновите свою версию Devise (с bundle update devise).

Электронные письма без учета регистра уже присутствуют в Devise, просто убедитесь, что у вас есть эта конфигурация:

# devise.rb
Devise.setup do |config|
  config.case_insensitive_keys = [:email ]
end

В любом случае, поскольку у вас, похоже, отсутствуют некоторые флеш-сообщения и эта конфигурация, возможно, было бы лучше, если бы вы просто перезапустили генератор:

rails generate devise:install

Затем вы должны позволить Devise перезаписать некоторые файлы, но сначала убедитесь, что вы сделали резервную копию своих.

person Ashitaka    schedule 25.01.2013
comment
Привет, извините за поздний ответ. Я полностью согласен с вами по поводу нечувствительных электронных писем, но это не моя проблема (и не ее причина). Проблема связана с flash[:messages]. Я попытался восстановить файл install. Это не помогло... - person ndemoreau; 29.01.2013