2014-03-19 55 views
4

我有一个Devise自定义问题,我正在努力。如何将查询参数传递给Devise的登录页面

我们有一些查询参数包含在某些电子邮件链接中,如果用户在点击链接时尚未通过身份验证,那么这些链接需要传递给登录URL。例如,如果电子邮件中的链接是:

http://my.host.com/my/path/1234?x=y&foo=bar 

我想未授权的用户重定向到

http://my.host.com/login/?foo=bar 

即一个特定的查询参数需要传递 - 我不知道关心登录表单上的任何其他人,但如果所有查询参数都必须通过,我可以忍受这一点。

我已经找到了SO和Docs &来源于Devise和Warden,但是找不到一个直截了当的方法来做到这一点。道歉,如果我失去了明显的东西。

+0

难道我的回答解决了问题? –

回答

3

最后,我们得到了我们想要的下降非常稍许不同的路线的影响。

与其将param包含在重定向到登录的查询URL中,我们能够修改相关的代码来接受会话参数。

然后,在application_controller.rb

class ApplicationController < ActionController::Base 
    before_filter :persist_login_param 
    ... 

    def persist_login_param 
    session[:foo] = params[:foo] 
    end 
end 

而在会话控制器,我们作用于会话参数的值,将其丢弃一次。

稍微凌乱,但它工作并获取代码现在推出到生产,这是重要的事情!

+0

我不认为这适用于未经验证的用户。在'before_filter'有机会行动之前,Devise会将它们重定向到登录页面。至少这是我在Devise 2.0.4和Rails 2.2.2的设置中发现的。 – evanrmurphy

+0

没关系,这确实有用!你只需要确保':persist_login_param'在'before_filter'链中的':authenticate_user!'之前。谢谢,斯科特。 – evanrmurphy

0

对于未认证用户,以便通过具体PARAMS foo=barhttp://my.host.com/my/path/1234?x=y&foo=bar到您的登录,执行如下:

假设上述电子邮件中的链接进入到行动myaction然后将下面的代码添加到myaction

def myaction 
    if member_signed_in? 
     redirect_to root_path 
    else 
     ## If user is unauthenticated direct them to login page with specific params 
     redirect_to new_member_session_path(foo: params[:foo]) 
    end 
    end 

上述行动将通过PARAMS foo到色器件的登录页面,并在浏览器地址栏的实际链接看起来如下:

http://my.host.com/login?foo=bar ## Without/after login 

您可以通过重写Devise :: SessionsController来访问参数。例如:

class Users::SessionsController < Devise::SessionsController 
    ... 
    def new 
    @foo = params[:foo] 
    super 
    end 
    ... 
end 
+0

不幸的是,因为认证发生在调用堆栈的更远处,在这种情况下#myaction永远不会被调用,除非用户已经被认证。 –

0

可以使用,除非在before_action语句,那么unauthentication用户可以看到任何色器件控制器动作

class ApplicationController < ActionController::Base 
    ... 
    before_filter :sending_params 
    before_action :check_auth, unless: :devise_controller? 

    ... 

    protected 

    def check_auth 
    unless user_signed_in? 
     redirect_to new_user_session_path(sending_params) 
    end 
    end 

    def sending_params 
    params.permit(:first_param, :second_param) 
    end 
    ... 

,并且可以访问到PARAMS不产生由生成设计的控制器设计的观点和看法使用

<%= params[:first_param] %> 

如果需要将参数发送到omniauth控制器,您可以在设计视图中更改链接

<%= link_to 'Sign in by provider', omniauth_authorize_path(:user, :provider, first_param: params['first_param']) %> 

其中:用户 - 名色器件模型,:供应商 - 名omniauth提供商(:Facebook的即)

在omniauth控制器,你可以使用

def first_param 
    request.env['omniauth.params']['first_param'] ||= '' 
end