Devise-Zaloguj się za pomocą Ajax

Czy istnieje możliwość modyfikacji devise SessionsController dla komunikacji ajax?

Edytuj

Znalazłem rozwiązanie i zamieściłem je w odpowiedziach, dzięki

Author: the_ousek, 2015-06-14

1 answers

1. Generowanie kontrolerów Devise, dzięki czemu możemy je modyfikować

rails g devise:controllers

Tutaj wpisz opis obrazka

Teraz mamy wszystkie kontrolery w katalogu app/controllers/[model]

2. Edytuj trasy.rb

Ustawmy Devise, aby korzystał z naszego zmodyfikowanego kontrolera SessionsController

Najpierw dodaj ten kod (oczywiście change: users do twojego modelu devise) do config/routes.rb

devise_for :users, controllers: {
  sessions: 'users/sessions'
}

3. Modyfikuj sessions_controller.rb

Tutaj wpisz opis obrazka

Znajdź metodę create i zmień ją na

def create
  resource = User.find_for_database_authentication(email: params[:user][:email])
  return invalid_login_attempt unless resource

  if resource.valid_password?(params[:user][:password])
    sign_in :user, resource
    return render nothing: true
  end

  invalid_login_attempt
 end

Utwórz nową metodę po protected

def invalid_login_attempt
  set_flash_message(:alert, :invalid)
  render json: flash[:alert], status: 401
end

4. devise.rb

Wstaw to do config/initializers / devise.rb

config.http_authenticatable_on_xhr = false
config.navigational_formats = ["*/*", :html, :json]

5. Nieprawidłowa wiadomość e-mail lub hasło]}

Wstaw nową wiadomość do config/locales/devise.en.yml pod sesjami

invalid: "Invalid email or password."

sesje

6. Widok

= form_for resource, url: session_path(:user), remote: true do |f|
  = f.text_field :email
  = f.password_field :password
  = f.label :remember_me do
    Remember me
    = f.check_box :remember_me
  = f.submit value: 'Sign in'

:javascript
  $(document).ready(function() {
    //form id
    $('#new_user')
    .bind('ajax:success', function(evt, data, status, xhr) {
      //function called on status: 200 (for ex.)
      console.log('success');
    })
    .bind("ajax:error", function(evt, xhr, status, error) {
      //function called on status: 401 or 500 (for ex.)
      console.log(xhr.responseText);
    });
  });

Ważna rzecz remote: true

Powodem, dla którego używam status 200 lub 401 w przeciwieństwie do {status: 'true' } jest mniejszy rozmiar danych, więc jest znacznie szybszy i czystszy.

Wyjaśnienie

Po zalogowaniu, dostajesz te dane w params

action: "create"
commit: "Sign in"
controller: "users/sessions"
user: {
  email: "[email protected]"
  password: "123"
  remember_me: "0"
}
utf8: "✓"

Przed podpisaniem musisz autoryzować użytkownika.

resource = User.find_for_database_authentication(email: params[:user][:email])

Użytkownik.find_for_database_authentication

Jeśli użytkownik zostanie znaleziony, zasób będzie wypełniony czymś w rodzaju

created_at: "2015-05-29T12:48:04.000Z"
email: "[email protected]"
id: 1
updated_at: "2015-06-13T19:56:54.000Z"

Inaczej będzie

null
Jeśli użytkownik jest uwierzytelniony, mamy zamiar zweryfikować jego hasło.]}
if resource.valid_password?(params[:user][:password])

I na koniec Zaloguj się

sign_in :user, resource

Źródła

SessionsController

Pomógł mi Andreas Lyngstad

 37
Author: the_ousek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 10:49:42