Autoryzacja użytkownika (logowanie, błąd w przypadku niewłaściwych danych)

Witam serdecznie. Ponownie wróciłem do Rails, tym razem bardziej poważnie. Pisząc w ramach nauki system obsługi użytkowników natrafiłem na problem, który nie jestem pewien jak właściwie ugryźć. Formularz logowania jest w new, a samo logowanie w create:

 def new
      @user = User.new
  end

  def create
      if @user = User.find_by_nickname(params[:session][:nickname])
          if @user = @user.authenticate(params[:session][:password])
              session[:user_id] = @user.id
              redirect_to @user
          end
      end

      if !@user
          render "new"
      end
  end

i teraz tak: jak widać w momencie, gdy nie zostanie odnaleziony żaden użytkownik zostaje wygenerowany ponownie formularz logowania. Jednak wtedy nie mam jak wyświetlić błędu, że nie odnaleziono użytkownia (@user będzie nil, a błędy defaultowo wyświetlam dzielonym partialem: @user.errors - tutaj trafiają w końcu np. komunikaty walidacji). Stąd pytanie: jak należałoby taką informację przekazać? Najwygodniej byłoby ręczne wywołanie błędu, że nie odnaleziono użytkownika, tak, żeby spełniał warunki wyświetlania błędów z tablicy .errors. Ale po 1. nie wiem jak to zrobić. Używanie czegoś w stylu flash[] nie uśmiecha mi się, ponieważ wiąże się z tworzeniem dodatkowego kodu, który musi być obsługiwany przez ww. partial, żeby wszystko trzymało się kupy.

Jak to powinno być zrealizowane w rails-way?

użyj Devise

W przypadku nauki wymyślanie koła na nowo uważam za słuszne, więc podziękuję za automat :smile:

Możesz stworzyć osobny model np. Session, który będzie trzymał walidacje do formularza używając ActiveModel::Model.

Wtedy wywołanie w kontrolerze będzie dokładnie takie samo jak dla innych modeli:

@session = Session.new(session_params)
if @session.valid?
  # Zaloguj użytkownika, przekieruj
else
  render :new
end

Możesz zerknąc jak to jest zaimplementowane w bardzo prostym gemie: https://github.com/cowbell/active_model-session

PS: Nie używaj devise :wink:

1 Like

Szprytne! Spróbuję to zaimplementować!

Na railscast Rayan pisze z palca, mozna obejrzec

Napisałem to po swojemu i korzystając z poprzednio wspomnianego gema. Nie rozumiem tylko kiedy wywoływana jest funkcja user:

Po prostu nie widzę tego.

Pierwszy raz metoda user jest wywoływana w linijce https://github.com/cowbell/active_model-session/blob/333a5d7da91d31a2bc9a8fd0c7a296af033ce1ba/lib/active_model/session.rb#L12 w procu.

niestety nie działa to jak automat, swoje też trzeba wiedzieć i to dość sporo

has_password jest wystarczające na moje aktualne potrzeby, więc zostanę przy nim.