2010-12-02 7 views
9

Tengo un problema de novato. Quería diseñar para redireccionar a la última página que el usuario visitó. Así que hice lo siguiente ...Redireccionar lazo con Devise after_sign_in_path_for

def after_sign_in_path_for(resource) 
    request.referer 
end 

Funciona muy bien ... excepto si el usuario está realmente registrando a través de la forma original que provoca un bucle de redireccionamiento.

me trataron

def after_sign_in_path_for(resource) 
    if (request.referer == "https://stackoverflow.com/users/sign_in") 
    :pages_home 
else 
    request.referer 
end 

end 

pero eso no es de trabajo, muy probablemente porque no tengo ni idea de lo que realmente está volviendo request.referer cuando encuentra la página de inicio de sesión de usuario original (www.example.com/users/sign_in)

¿Alguna idea?

tldr; Usando el ingenio, quiero redireccionar a la página conectó a partir de (es decir/blog/4) a menos que la página es/usuarios/sign_in

resuelto:

Matchu tenía razón. El request.referer regresaba el dominio, así ...

http://example.com/users/sign_in 

(nota: no hay prefijo www)

Todavía estoy interesado en una alternativa a request.referer si es una manera insegura o ineficaz .

+0

el árbitro probablemente contiene el nombre de dominio:/ – Matchu

+0

Esto funciona bastante bien para mí: http://stackoverflow.com/questions/5255283/how-do-i-make- idear-redirigir-a-una-ubicación-almacenada-después-de-iniciar sesión-o-registrar –

Respuesta

12

No redirija a los remitentes; generalmente es una mala idea.

En su lugar, pase un valor de next en la cadena de consulta o en los datos de formulario. Tal vez usar algo como:

def after_sign_in_path_for(resource) 
    params[:next] || super 
end 

Cuando un usuario intenta visitar una página que requiere autenticación (por ejemplo, /admin/posts/3/edit) la autenticación before_filter emite un redirect_to new_session_url(:next => request.path). A continuación, codifique la acción de inicio de sesión y visualice para conservar el parámetro :next query-string.

+0

No estoy seguro de lo que quiere decir. Como una entrada oculta: ¿siguiente que contiene la url actual? – Elxx

+0

Marcaré a Justice como la respuesta aceptada a menos que Matchu pueda volver a publicar como respuesta o Justice puede explicar una alternativa a request.referer – Elxx

2

¿Qué tal esto:

def after_sign_in_path_for(resource) 
    sign_in_url = url_for(:action => 'sign_in', :controller => 'users', :only_path => false, :protocol => 'http') 
    if (request.referer == sign_in_url) 
    super 
    else 
    request.referer 
    end 
end 
+0

Esto funcionó para mí. Tuve que cambiar la segunda línea a "sign_in_url = url_for (: action => 'new',: controller => 'sessions',: only_path => false,: protocol => 'http')" –

2

Tomé la respuesta de la Justicia y la cambié a utilizar sesiones en su lugar.

Por lo que puedo ver, las sesiones son más simples que agregar la url como param, pero pueden comportarse inesperadamente cuando un usuario navega por un sitio en varias pestañas, por ejemplo. El uso de sesiones es menos RESTfull, pero más simple y más limpio.

Al utilizar CanCan, el establecimiento de la redirección de la ruta se puede hacer en un lugar central: el lugar que maneja el "acceso denegado" excepciones:

rescue_from CanCan::AccessDenied do |exception| 
    if current_user.nil? 
     session[:next] = request.fullpath 
     puts session[:next] 
     redirect_to new_user_session_path, :alert => exception.message 
    else 
     render :file => "#{Rails.root}/public/403.html", :status => 403 
    end 
    end 

Pero se puede establecer en cualquier lugar, en realidad:

def edit 
    if current_user.roles[:moderator].nil? 
    session[:next] = "/contact" 
    redirect_to new_user_session_path, :alert => "please contact the moderator for access" 
    end 
    # ... 
end 

Luego, en ApplicationController, puede volver a usar ese valor de sesión. Asegúrate de eliminarlo también, sin embargo.

def after_sign_in_path_for(resource) 
    path = '' 
    if session[:next] 
     path = session[:next] 
     session[:next] = nil 
    else 
     path = super 
    end 

    path 
    end 
0

Aquí está mi código para rescue_from CanCan.

rescue_from CanCan::AccessDenied do |exception| 
    if current_user.nil? 
    session[:next] = request.fullpath 
    puts session[:next] 
    redirect_to login_url, :alert => "You have to be logged in to continue" 
    else 
    #render :file => "#{Rails.root}/public/403.html", :status => 403 
    if request.env["HTTP_REFERER"].present? 
     redirect_to :back, :alert => exception.message 
    else 
     redirect_to root_url, :alert => exception.message 
    end 
    end 
end 

Lo que hace: - si el usuario no está conectado, se redirige a la página de acceso - si el usuario está conectado, pero no tienen la capacidad de ver la acción, redirecciona ya sea atrás o a la página raíz con el mensaje de alerta de destello