tutorial rails instalar docs auth ruby-on-rails ruby ruby-on-rails-4 authentication devise

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.

  1. El usuario crea un proyecto de prueba.
  2. 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.
  3. Si el usuario invitado se registra, debe iniciar sesión y el proyecto de prueba debe asignarse al nuevo usuario real.
  4. 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.