ruby-on-rails - docs - instalar devise rails
Rails 4-Devise, los usuarios invitados hacen que la cadena de filtro se detenga (3)
Acabo de empezar a trabajar en una aplicación de Rails 4 (4.2.3) donde uso Devise
para la autenticación del usuario. Quiero que los usuarios puedan jugar con la aplicación antes de iniciar upp creando un proyecto de prueba e iniciar sesión como un usuario invitado. Cuando el usuario se registra (o in), quiero asignar el proyecto de prueba al nuevo usuario actual.
He estado siguiendo esta guía de Platformatec: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user
La creación del usuario invitado funciona, pero cuando se registra o se inicia con una sesión de usuario invitado activa, aparece el siguiente error:
Filter chain halted as :require_no_authentication rendered or redirected
Si borro mi sesión, funciona. El método que administra mi usuario invitado se ve así:
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
Como se mencionó, la creación de usuarios invitados parece funcionar bien. Pero esta lógica nunca sucede:
# 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
Estoy bastante seguro de que mi sesión de usuario invitado está en conflicto con mi nuevo usuario y causa este error de cálculo (ya que el usuario invitado nunca se elimina al registrarse):
Filter chain halted as :require_no_authentication rendered or redirected
El resto de mi lógica de usuario invitado se parece más o menos exactamente a esta guía vinculada: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user . También agregué el código del párrafo / ejemplo de Autenticación: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the -current_user-helper .
¿Alguna idea sobre lo que me estoy perdiendo, y cómo puedo obtener mi current_or_guest_user
para eliminar al usuario invitado en el registro y la firma cuando usa Devise?
Actualizar
Así es como se ven mis rutas actualmente:
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"
Actualización 2
La guía tiene la siguiente declaración:
Cuando (y si) el usuario se registra o inicia sesión, eliminamos el usuario invitado y borramos la variable de sesión.
No explica mucho cómo y dónde hacerlo. Supongo que tengo que llamar a current_or_guest_user
alguna parte otra vez. Pero no estoy seguro de dónde, ya que no estoy tan familiarizado con Devise.
Actualización 3
Para hacerlo un poco más claro. Estos son los pasos que quiero lograr.
- El usuario crea un proyecto de prueba.
- Tras la creación del proyecto de prueba, se crea un usuario invitado y una sesión. El usuario invitado debe eliminarse una vez que finaliza la sesión o # 3.
- Si el usuario invitado se registra, debe iniciar sesión y el proyecto de prueba debe asignarse al nuevo usuario real.
- El usuario invitado debería ser eliminado.
Creo que el problema está causado por la estrategia guest_user warden a la que se hace referencia en la guía. Dado que Devise comprueba si hay una sesión válida de guardián antes de iniciar sesión, se produce una redirección y aparece un mensaje intermitente:
if authenticated && resource = warden.user(resource_name)
flash[:alert] = I18n.t("devise.failure.already_authenticated")
redirect_to after_sign_in_path_for(resource)
end
¡Entonces, si no necesitas estrictamente eso, autentifícate! método para trabajar en el usuario invitado, simplemente puede desactivar esa estrategia y debería funcionar.
La respuesta anterior carece de explicación, el método loggin_in
no se está llamando porque no ha definido su devolución de llamada
En su ApplicationController necesita definir y luego establecer la devolución de llamada de la siguiente manera:
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
¿Has intentado usar la gema de los invitados de los invitados ? implementa de fábrica esta funcionalidad, en lugar de hacerlo desde cero ...
Verifique este controlador de ejemplo que está implementando el inicio de sesión de invitado. Espero eso ayude.
Gracias por sus respuestas skahlert y SsouLlesS. Saltarse la estrategia de guardián ayudó y la definición de devoluciones de llamada parece un enfoque limpio. Además de eso, tuve otros problemas.
Una fue que mis controladores personalizados de Devise nunca fueron llamados. Se creó otra pregunta para eso: Rails 4: ideó_para no usar controladores personalizados . La solución fue que utilicé la URL incorrecta en mi formulario de suscripción modal. Mi formulario ahora se ve así:
= form_for(resource, as: resource_name, url: user_registration_path do |f|
Luego hice lo que skahlert sugirió y eliminé la estrategia warden de mi aplicación.
Una vez que mi controlador personalizado Users::RegistrationsController < Devise::RegistrationsController
se llamó, decidí anular la acción de crear. No está completamente probado, pero se ve así:
# 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
Todo parece funcionar ahora. Podría hacer algunas refactorizaciones y posiblemente probar el enfoque de devolución de llamada que SsouLlesS sugirió en su respuesta.