ruby-on-rails - rails - devise:: registrationscontroller update
Rails: Warden/Devise-Cómo capturar la URL antes de iniciar sesión/acceso fallido (5)
Estoy tratando de averiguar cómo redirigir a un usuario a la página desde la que inició sesión (o no se pudo iniciar sesión) usando Warden / Devise. Me imagino que hay una variable de sesión en algún lugar que está disponible o podría estar disponible.
Ej. Escenario 1: el usuario no autorizado va a la página protegida X; Redirigido a la página de inicio de sesión; El usuario inicia sesión; Usuario redirigido a página protegida x
Escenario 2: el usuario no autorizado desea realizar una acción protegida en la página x; El usuario hace clic en el enlace de inicio de sesión; El usuario inicia sesión; Usuario redirigido a la página x donde ahora está disponible la acción
Todos los punteros son apreciados.
¡Gracias!
Aquí está lo mejor que pude encontrar. Funciona perfectamente también con la autenticación de facebook. al agregar más restricciones a la adición de URL a la variable de sesión, puede eliminar más y más rutas que no quiere que el usuario regrese también (por ejemplo, devoluciones de llamada, páginas de bienvenida, páginas de destino, etc.)
#ApplicationsController
after_filter :store_location
def store_location
session[:previous_urls] ||= []
# store unique urls only
session[:previous_urls].prepend request.fullpath if session[:previous_urls].first != request.fullpath && request.fullpath != "/user" && request.fullpath != "/user/login" && request.fullpath != "/" && request.fullpath != "/user/logout" && request.fullpath != "/user/join" && request.fullpath != "/user/auth/facebook/callback"
# For Rails < 3.2
# session[:previous_urls].unshift request.fullpath if session[:previous_urls].first != request.fullpath
session[:previous_urls].pop if session[:previous_urls].count > 3
end
def after_sign_in_path_for(resource)
@url = session[:previous_urls].reverse.first
if @url != nil
"http://www.google.com" + @url
else
root_path
end
end
Puede usar request.referer
para obtener la URL
anterior.
Si está utilizando CanCan para la autorización, puede hacerlo agregando lo siguiente. De lo contrario, debería poder adaptar los conceptos a su sistema de autorización actual.
app / controllers / application_controller.rb
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = exception.message
if user_signed_in?
redirect_to root_url
else
# Adds the protected page to the login url but only if the user is not logged in
redirect_to login_path(:next => request.path)
end
end
def after_sign_in_path_for(resource_or_scope)
# if a protected page found, then override the devise after login path
params[:user]["next"] || super
end
app / views / devise / session / new.html.erb
<% if params[:next] %>
<%= f.hidden_field :next, :value => params[:next] %>
<% end %>
En lugar de utilizar las variables de sesión, esta solución utiliza parámetros en la URL para realizar un seguimiento de la página protegida.
Wow, me acabo de dar cuenta de que el devise (3.5.2)
hace todo esto por sí mismo detrás de la escena (en torno a la Devise::SessionsController#new
acción de Devise::SessionsController#new
), no se requieren modificaciones adicionales del controlador.
Si necesita store
/ get
explícitamente la location
anterior, consulte mi respuesta anterior:
Actualmente ( otoño de 2015 ) hay una forma más atractiva de hacerlo:
Devise::Controllers::StoreLocation#store_location_for
:
# Stores the provided location to redirect the user after signing in.
# Useful in combination with the `stored_location_for` helper.
store_location_for :user, dashboard_path
redirect_to user_omniauth_authorize_path :facebook
Devise::Controllers::StoreLocation#stored_location_for
:
# Returns and delete (if it''s navigational format) the url stored in the session for
# the given scope. Useful for giving redirect backs after sign up:
redirect_to stored_location_for(:user) || root_path
Los métodos manejan la clave de session
relacionada y la eliminación de valores después de la lectura, todo lo que necesita es proporcionar su :resource
clave de :resource
( :user
en el ejemplo anterior) y una ruta para almacenar ( dashboard_path
en el ejemplo anterior). Vea la source para los detalles.
En cuanto a la respuesta real será algo así:
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied, with: :access_denied
# ...
private
def access_denied(exception)
store_location_for :user, request.path
redirect_to user_signed_in? ? root_path : new_user_session_path, alert: exception.message
end
def after_sign_in_path_for(resource)
stored_location_for(:user) || root_path
end
end
Existe un método de ayuda de after_sign_in_path_for(resource)
llamado after_sign_in_path_for(resource)
( http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers ), y una variable de session[:"user.return_to"]
llamada session[:"user.return_to"]
que almacena la última url. El método after_sign_in_path_for
necesita devolver una cadena, luego el dispositivo utiliza automáticamente esta ruta para redirigir al usuario después de iniciar sesión.
En mi controlador de aplicación, puse lo siguiente que redirige a mis usuarios a la página de inicio si la variable de sesión no está establecida:
def after_sign_in_path_for(resource)
(session[:"user.return_to"].nil?) ? "/" : session[:"user.return_to"].to_s
end