2015-11-16 25 views
7

Ho appena iniziato a lavorare su un'app Rails 4 (4.2.3) in cui utilizzo Devise per l'autenticazione dell'utente. Voglio che gli utenti siano in grado di giocare con l'app prima di firmare upp creando un progetto di test e accedendo come utente ospite. Quando l'utente si iscrive (o in) voglio assegnare il progetto di test al nuovo utente corrente.Rails 4 - Devise, gli utenti guest causano il blocco della catena di filtri

Ho seguito questa guida da Platformatec: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

Creare le ospiti lavori utente, ma al momento della firma o con una sessione utente guest attiva ottengo il seguente errore:

Filter chain halted as :require_no_authentication rendered or redirected 

Se Ho cancellato la mia sessione funziona. Il metodo che gestisce il mio utente guest è il seguente:

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 

Come accennato, la creazione di utenti guest sembra funzionare correttamente. Ma questa logica non succede mai:

# 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 

Sono abbastanza sicuro che la mia sessione utente guest è in conflitto con il mio nuovo utente e causa questo errore Devise (dal momento che l'utente guest non viene mai cancellato al momento della registrazione):

Filter chain halted as :require_no_authentication rendered or redirected 

Il resto della logica utente guest sembra più o meno esattamente come questa guida collegata: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user. Ho anche aggiunto il codice dal paragrafo/esempio di autenticazione: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the-current_user-helper.

Qualche idea su cosa mi manca e su come posso ottenere il mio current_or_guest_user per eliminare l'utente ospite alla registrazione e alla firma quando uso Devise?

Aggiornamento

Questo è come i miei percorsi appaiono attualmente:

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

La guida ha la seguente dichiarazione:

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

Non spiega molto come e dove farlo. Suppongo di dover chiamare di nuovo current_or_guest_user da qualche parte. Ma non sono sicuro di dove non sia così familiare con Devise.

Update 3

per renderlo un po 'più chiaro. Questa è la procedura che voglio raggiungere.

  1. L'utente crea un progetto di prova.
  2. Al momento della creazione del progetto di test viene creato un utente ospite e una sessione. L'utente ospite dovrebbe essere cancellato una volta che la sessione finisce o # 3.
  3. Se l'utente ospite si iscrive, deve accedere e il progetto di test deve essere assegnato al nuovo utente reale.
  4. L'utente guest deve essere eliminato.
+0

puoi pubblicare il file 'routes.rb' per favore? –

+0

@huzefabiyawarwala L'ho fatto ora. – Anders

+2

Ho provato la stessa cosa che stai cercando di implementare nella mia macchina e funziona bene, quindi potrebbe esserti perso qualcosa nel codice aggiuntivo che hai scritto oltre quello di ideare. Se è possibile, rimuovi il codice precedente e pubblica i controller esatti che hai attualmente. Sarebbe più facile eseguire il debug. –

risposta

1

Grazie per le vostre risposte skahlert e SsouLlesS. Saltare la strategia del custode ha aiutato e definire i callback sembra un approccio pulito. Oltre a ciò ho avuto altri problemi.

Uno era che i miei controller Devise personalizzati non venivano mai chiamati. Creato un'altra domanda per questo: Rails 4 - devise_for not using custom controllers. La soluzione è stata che ho usato l'URL sbagliato nel mio modulo di registrazione modale. La mia forma ora si presenta così:

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

poi ho fatto come suggerito skahlert e rimosso il warden strategy dalla mia app.

Dopo aver chiamato il mio controller personalizzato ho deciso di sovrascrivere l'azione di creazione. Non è completamente testato, ma assomiglia a questo:

# 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 

Tutto sembra funzionare ora. Potrebbe fare qualche refactoring e possibilmente provare l'approccio di callback suggerito da SsouLlesS nella sua risposta.

1

La risposta di cui sopra manca di spiegazione, il metodo loggin_in non viene chiamato perché non hai definito il callback

Nella tua ApplicationController è necessario definire e quindi impostare la richiamata in questo modo:

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 

Hai provato a usare la gemma devise-guests? implementa fuori dalla scatola questa funzionalità, invece di farlo da zero ...

Controllare questo controller example che sta implementando il login ospite. Spero che sia d'aiuto.

+1

Grazie. Esaminerà la vostra soluzione Sembra un modo pulito per farlo. Ho creato una risposta qui sotto con come l'ho fatto per ora, ho funzionato almeno. Sentiti libero di venire con suggerimenti per miglioramenti. – Anders

1

Penso che il problema sia causato dalla strategia guest_user warden a cui si fa riferimento nella guida. Poiché i controlli Devise per una sessione di guardia valida prima di accedere, causa un reindirizzamento e un messaggio flash appaia:

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

Quindi, se non strettamente necessario che autenticano! metodo per lavorare sull'utente ospite, puoi semplicemente disattivare quella strategia e dovrebbe funzionare.

+0

Grazie. Questo ha aiutato. Ho creato una risposta completa a tutto ciò che ho fatto qui sotto.Sentiti libero di aggiungere miglioramenti se conosci un approccio migliore. Grazie! – Anders