当用户验证失败时,将清除实例变量

时间:2018-03-05 09:20:30

标签: ruby-on-rails devise

在覆盖Devise::SessionsController时,我无法获取实例变量。

当未经身份验证的用户将商品添加到购物车时,我想将其重定向到登录页面并在经过身份验证后应用添加。

1。我将item_id作为网址参数传递:

localhost:3000/user_accounts/sign_in?item_id=42
  1. 我回到表单中的隐藏字段,我可以通过会话创建表单:
  2. 
    
    <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
      <%= f.hidden_field :item_id, value: params[:item_id] || @item_id %>
      ...
    <% end %>
    &#13;
    &#13;
    &#13;

    当Rails启动表单流时,URL参数将被删除:

    之前:

    localhost:3000/user_accounts/sign_in?item_id=42
    

    后:

    localhost:3000/user_accounts/sign_in
    

    当用户未通过身份验证时,我不想丢失item_id,因此我确保@item_id作为实例变量公开,因此我可以将其注入表单。

    然而,失败时,Rails(?)/ Devise(?)/ Warden(?)似乎清除了实例变量(出于安全原因?)。因此,@item_idnil

    请注意,在用户成功进行身份验证(通过URL参数)时效果很好。此外,我在注册过程中使用了这种相同的技术,它在成功(URL参数)和失败(实例变量)的情况下都有效。

    这是我对SessionsController的实现:

    class MySessionsController < Devise::SessionsController
      def create
        @item_id = parse_id(params[:user_account][:item])
        super do |account|
          add_to_cart(account, @item_id) if @item_id
        end
        flash.delete(:notice)
      end
    end
    

    你知道我怎么解决这个问题吗?

    我也愿意接受替代方案。

1 个答案:

答案 0 :(得分:0)

我错了。 Rails,Devise和Warden并没有对我的实例变量做一些阴暗的事情。我发现了重定向,解释了为什么上下文丢失了。

最后,我使用cookie来解决问题,正如@nattfodd所说的那样。这是微不足道的,我不知道为什么我没有想到它。

class MySessionsController < Devise::SessionsController
  def create
    item_id = parse_id(cookies.encrypted[:item])
    super do |account|
      add_to_cart(account, item_id) if item_id
      cookies.encrypted[:item] = ""
    end
    flash.delete(:notice)
  end
end

清洁,没有黑客。好。