me di cuenta que es tarde, pero esto podría ser de utilidad para otros. Tenía un requisito similar al tuyo. Básicamente, quería que un usuario ingresara una dirección de correo electrónico y persistiera al usuario como invitado. Una vez que el usuario es promovido a un usuario 'normal', vuelvo a habilitar la autenticación de contraseña. Primero, creé una estrategia warden basada en la gema devise-gullible. Hice una modificación al método authenticate
:
class Guest < Authenticatable
def authenticate!
resource = mapping.to.find_for_database_authentication(authentication_hash)
if resource
if resource.respond_to?(:guest?) and resource.guest?
success!(resource)
else
fail(:regular_user)
end
else
fail(:invalid)
end
end
end
que definen un invitado en mi modelo de usuario de la siguiente manera:
def guest?
self.roles.length == 0
end
estoy usando CanCan con legado y una HABTM para manejar los papeles. Actualmente, tengo un usuario 'regular' y un usuario 'administrador'. Un usuario es un invitado si todavía no tiene roles asignados.
Entonces, es necesario reemplazar el controlador de registros Idear:
class Users::RegistrationsController < Devise::RegistrationsController
prepend_before_filter :allow_params_authentication!, :only => :create
def create
resource = warden.authenticate(:guest,
{ scope: resource_name,
recall: "#{controller_path}#new" })
if resource
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
elsif warden.winning_strategy.message == :regular_user
set_flash_message :notice, :regular_user if is_navigational_format?
redirect_to new_session_path(resource_name)
else
super
end
end
end
Tenga en cuenta que la idea es que se intenta autenticar a un usuario que está ejecutando la estrategia para huéspedes. Si ya está registrado como invitado, solo fírmalo normalmente. Si la estrategia de invitado falla porque está registrado, pero ahora es un usuario regular, redirija a la página de inicio de sesión normal.
Ahora es posible conservar cierta información limitada que deseo recopilar de un invitado y no solicitarle que se registre por completo. Yo uso un modelo de usuario normal:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :omniauthable,
:token_authenticatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_and_belongs_to_many :roles
def self.new_with_session(params, session)
super.tap do |user|
if user.password.blank?
user.password = Devise.friendly_token[0,31]
# Also, we don't need to do email confirmation in this case.
# The user will have the guest role, and we'll do a confirmation
# when we promote him to a 'regular' user.
user.skip_confirmation!
end
end
end
def has_role?(role)
!!self.roles.find_by_name(role.to_s.camelize)
end
end
Tenga en cuenta que me auto-generar una contraseña en build_with_session
. Puede enviar un token de autenticación en el momento que elija y luego solicitarle al usuario que establezca una nueva contraseña en ese momento. También querrás cambiar su rol para que se convierta en un usuario regular (o hacer lo que sea que desees, ya no es un invitado).
Aquí es mi parcial que aparece en la primera página:
<%= simple_form_for(resource,
as: resource_name,
url: user_registration_path,
defaults: { required: false },
html: { class: 'well' },
wrapper: :bootstrap,
validate: true) do |f| %>
<%= f.error_notification %>
<fieldset>
<legend>New here? Let's get started!</legend>
<%= f.input :email, placeholder: '[email protected]', validate: { uniqueness: false } %>
<%= f.button :submit, "Get my quote!", class: 'btn-primary' %>
</fieldset>
<% end %>
Por lo tanto, esta forma funciona como un registro de huéspedes y formulario de acceso.Lo único que realmente no me importa hasta ahora es que el controlador de registros está manejando una autenticación, pero no vi una forma inmediata de evitar esto.
Implementé esta estrategia en mi directorio lib local. Asegúrese de configurar su ruta de carga de forma adecuada y agregue require 'devise_guest'
al config/initializers/devise.rb
.
Sí, eso es básicamente lo que estoy tratando de hacer. Voy a experimentar para ver cómo funciona esto. – spinlock
buena suerte - He implementado algo como esto y funciona bien - aquí a la hora de acostarse, pero lo revisaré por la mañana y trataré de responder cualquier pregunta si nadie más los recoge. – chrispanda