2015-11-16 14 views
7

Właśnie rozpocząłem pracę nad aplikacją Rails 4 (4.2.3), w której używam Devise do uwierzytelniania użytkownika. Chcę, aby użytkownicy mogli bawić się z aplikacją przed podpisaniem upp, tworząc projekt testowy i zalogować się jako gość. Kiedy użytkownik zarejestruje się (lub w), chcę przypisać projekt testowy do nowego bieżącego użytkownika.Szyny 4 - Wymyślanie, użytkownicy-goście powodują zatrzymanie łańcucha filtrów

śledzę ten poradnik z Platformatec: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

tworzeniu dzieła gościem, ale podczas rejestracji lub przy aktywnej sesji użytkownika gość pojawia się następujący błąd:

Filter chain halted as :require_no_authentication rendered or redirected 

Jeśli Wyczyszczę moją sesję, działa. Metoda, która zarządza użytkownikiem gościa, wygląda następująco:

def current_or_guest_user 
    if current_user 
    if session[:guest_user_id] && session[:guest_user_id] != current_user.id 
     logging_in 
     guest_user(with_retry = false).try(:destroy) 
     session[:guest_user_id] = nil 
    end 
    current_user 
    else 
    guest_user 
    end 
end 

Jak wspomniano, tworzenie użytkowników-gości wydaje się działać dobrze. Ale ta logika nie dzieje:

# should delete the guest user and clear the session. 
if current_user 
    if session[:guest_user_id] && session[:guest_user_id] != current_user.id 
    logging_in 
    guest_user(with_retry = false).try(:destroy) 
    session[:guest_user_id] = nil 
    end 
    current_user 

Jestem pewien, że moja sesja Gość jest sprzeczne z moim nowym użytkownikiem i powoduje ten błąd opracować (ponieważ nigdy Gość zostanie usunięty na znak w górę):

Filter chain halted as :require_no_authentication rendered or redirected 

Reszta logiki użytkownika-gościa wygląda mniej więcej tak jak ten powiązany przewodnik: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user. Dodałem także kod z akapitu Uwierzytelnienie/przykład: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the-current_user-helper.

Jakieś pomysły na temat tego, czego mi brakuje i jak mogę uzyskać current_or_guest_user, aby usunąć gościa podczas rejestracji i podpisywania podczas korzystania z Devise?

Aktualizacja

ten sposób moje trasy wyglądają obecnie:

devise_for :users, controllers: { sessions: "users/sessions", registrations: "users/registrations" } 

root :to => 'public#index' 

resources :apps 

get 'users/show', to: "users#show" 
get 'users', to: "users#index" 

post 'guests/receive_guest', to: "guests#receive_guest" 

UPDATE 2

The instrukcji mają następujące oświadczenie:

When (and if) the user registers or logs in, we delete the guest user and clear the session variable.

Nie wyjaśnia, jak i gdzie to zrobić. Zgaduję, że muszę znów zadzwonić pod numer current_or_guest_user. Ale nie jestem pewien, skąd nie jestem zaznajomiony z Devisem.

Update 3

Aby uczynić go nieco bardziej jasne. Oto kroki, które chcę osiągnąć.

  1. Użytkownik tworzy projekt testowy.
  2. Po utworzeniu projektu testowego zostaje utworzony gość i sesja. Gość powinien zostać usunięty po zakończeniu sesji lub # 3.
  3. Jeśli gość zarejestruje się, powinien on zostać zalogowany, a projekt testowy powinien zostać przypisany do nowego prawdziwego użytkownika.
  4. Użytkownik-gość powinien zostać usunięty.
+0

Czy możesz opublikować swój plik 'routes.rb'? –

+0

@huzefabiyawarwala Zrobiłem to teraz. – Anders

+2

Próbowałem tego samego, co próbujesz zaimplementować w mojej maszynie i działa dobrze, więc może być to, że brakuje ci czegoś w dodatkowym kodzie, który napisałeś, poza tym, który wymyślisz. Jeśli to możliwe, usuń powyższy kod i opublikuj dokładnie te kontrolery, które masz obecnie. To byłoby łatwiejsze do debugowania. –

Odpowiedz

1

Dzięki za twoje odpowiedzi skahlert i SsouLlesS. Pominięcie strategii strażników pomogło i zdefiniowanie callbacków wydaje się być czystym podejściem. Poza tym miałem inne problemy.

Jednym z nich było to, że moi zwyczajowi kontrolerzy Devisa nigdy nie zostali wezwani. Utworzono kolejne pytanie: Rails 4 - devise_for not using custom controllers. Rozwiązaniem było to, że użyłem niewłaściwego adresu URL w moim formularzu rejestracji modalnej. Moja forma wygląda teraz tak:

= form_for(resource, as: resource_name, url: user_registration_path do |f| 

Potem zrobiłem jak skahlert sugerowane i usunął warden strategy z mojej aplikacji.

Po wywołaniu kontrolera niestandardowego postanowiłem zastąpić akcję tworzenia. Nie jest całkowicie przetestowany, ale wygląda na to:

# POST /resource 
def create 
    # Delete guest user and reset session. 
    new_user_from_guest = guest_user 
    guest_user(with_retry = false).try(:destroy) 
    session[:guest_user_id] = nil 

    build_resource(sign_up_params) 

    resource.save 
    yield resource if block_given? 
    if resource.persisted? 
    if resource.active_for_authentication? 
     set_flash_message :notice, :signed_up if is_flashing_format? 
     sign_up(resource_name, resource) 

     # Assign the guest users app to the new current user. 
     new_user_from_guest.apps.each do |app| 
     app.user_id = current_user.id 
     app.save! 
     end 
     respond_with resource, location: after_sign_up_path_for(resource) 
    else 
     set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format? 
     expire_data_after_sign_in! 
     respond_with resource, location: after_inactive_sign_up_path_for(resource) 
    end 
    else 
    # Reset test user if signup fails, I have not tested this part yet. 
    guest_user 
    guest_user.apps << new_user_from_guest.apps 
    guest_user.save! 

    clean_up_passwords resource 
    set_minimum_password_length 
    respond_with resource 
    end 
end 

Wszystko wydaje się teraz działać. Mógłby trochę refaktoryzacji i ewentualnie spróbować podejścia callback, które SsouLlesS zasugerował w swojej odpowiedzi.

1

Powyższa odpowiedź brakuje wyjaśnienia, metoda loggin_in nie jest nazywany, ponieważ nie określono swoją zwrotnego

W swojej ApplicationController trzeba zdefiniować, a następnie ustawić zwrotnego tak:

define_callbacks :logging_in_user 
set_callback :logging_in_user, :before, :transfer_guest_user_actions_to_current_user 

def transfer_guest_user_actions_to_current_user 
    # todo 
end 

Czy próbowałeś użyć klejnotu devise-guests? implementuje od razu tę funkcję, zamiast robić to od zera ...

Sprawdź ten kontroler example, który wprowadza logowanie gościa. Mam nadzieję, że to pomoże.

+1

Dziękuję. Przyjrzymy się Twojemu rozwiązaniu. Wydaje się, że to czysty sposób. Poniżej stworzyłem odpowiedź z tym, jak to zrobiłem na razie, ale przynajmniej działa. Zapraszam do zgłaszania sugestii dotyczących ulepszeń. – Anders

1

Myślę, że przyczyną problemu jest strategia gościa guest_user wymieniona w przewodniku. Ponieważ kontrole opracować dla ważnej sesji warden zanim się zalogujesz, powoduje przekierowanie i komunikat lampy błyskowej pojawiają się:

if authenticated && resource = warden.user(resource_name) 
    flash[:alert] = I18n.t("devise.failure.already_authenticated") 
    redirect_to after_sign_in_path_for(resource) 
end 

Więc jeśli nie trzeba, że ​​ściśle uwierzytelniania! metoda pracy z użytkownikiem-gościem, możesz po prostu dezaktywować tę strategię i powinna działać.

+0

Dziękuję. To pomogło. Stworzyłem pełną odpowiedź na wszystko, co zrobiłem poniżej.Możesz dodać do niego ulepszenia, jeśli znasz lepsze podejście. Dzięki! – Anders