【问题标题】:spree customizing the create user sessions actionspree 自定义创建用户会话操作
【发布时间】:2015-07-13 12:55:32
【问题描述】:

我使用 STI 向我的 Spree::User 模型类添加了继承。我有一个 :type 列,它可以是(Spree::Guest、Spree::Writer 或 Spree::Reader)。

在我的管理员身份验证中,我只想验证作者和读者。解决此问题的最佳选择是什么?

我试图将创建操作覆盖为:

def create
  authenticate_spree_user!

  if spree_user_signed_in? && (spree_current_user.role?(:writer) || spree_current_user.role?(:reader))
    respond_to do |format|
      format.html {
        flash[:success] = Spree.t(:logged_in_succesfully)
        redirect_back_or_default(after_sign_in_path_for(spree_current_user))
      }
      format.js {
        user = resource.record
        render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
      }
    end
  else
    flash.now[:error] = t('devise.failure.invalid')
    render :new
  end
end

在这种情况下,当尝试使用 :guest 类型的用户进行身份验证时,它会重定向到带有无效失败消息 (ok) 的新操作,但不知何故用户通过了身份验证 (nok)。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 spree spree-auth-devise


    【解决方案1】:

    我认为这不是解决这个问题的好方法,控制器应该只是一个控制器。我宁愿走那条路:

    Spree 使用 cancancan(或旧分支中的 cancan)进行授权,即 how Spree implements that。我不知道你为什么想要 STI 解决方案 - 我会为此创建新的自定义 Spree::Role,但正如我所说,我不知道你为什么选择 STI 方式 - 这也应该可以正常工作。 无论如何,您可以为该能力文件添加一个装饰器,并对user.is_a? Spree::Guest 等进行额外检查,或者通过register_ability 注册新能力 - 类似于this。

    第三个链接最重要的部分(或万一它断开):

    # create a file under app/models (or lib/) to define your abilities (in this example I protect only the HostAppCoolPage model):
    
    Spree::Ability.register_ability MyAppAbility
    
    class MyAppAbility
      include CanCan::Ability
    
      def initialize(user)
        if user.has_role?('admin')
          can manage, :host_app_cool_pages
        end
      end
    
    end
    

    我个人会选择装饰器选项(代码似乎有点不清楚,但在确定可以由谁管理的内容时更清晰 - 请记住abilities precedence),但这取决于你。如果您有任何具体问题,请随时提出,如果可以的话,我会提供帮助。

    编辑:因此,如果您想禁用某些用户的身份验证,也许只是利用现有的设计方法?像这样的东西(在你的user 模型中):

    def active_for_authentication?
      super && self.am_i_not_a_guest? # check here if user is a Guest or not
    end
    
    def inactive_message
      self.am_i_not_a_guest? ? Spree.t('devise.failure.invalid') : super # just make sure you get proper messages if you are using that module in your app
    end
    

    【讨论】:

    • 感谢 zrl3dx 的回答和解决方案。我使用 STI 是因为我希望我的不同类型的用户能够根据他们的类型从多个平台注册和验证。因此 Spree::Guest 类型的用户可以在另一个平台上注册为 Spree::Reader 但我希望在每个平台上经过身份验证的用户必须是正确的用户。为此,我使用具有范围的唯一性电子邮件::类型。另一方面,你能解释一下什么可以管理吗, :host_app_cool_pages 可以吗?
    • @Moh:这意味着管理员可以对模型 HostAppCoolPages 执行任何操作 - 您还可以添加其他预定义(即读取)或自定义操作,请在此处查看:github.com/CanCanCommunity/cancancan/wiki/…
    • 是的,我已经覆盖了我的能力模型类,每个用户都可以访问或管理特定的模型和控制器。但我的问题实际上在于身份验证,例如,我希望 Spree::Guest 类型的用户永远无法访问 Spree::Reader 和 Spree::Writer 等其他人可以访问的平台。您认为您的答案对我的问题仍然有效吗?如果是这样或者我没有解释清楚,请告诉我。
    • 嗨@zrl3dx,我在方法上犯了一个错误,现在它们似乎正在工作。此外,我仍然面临一个危急情况,我可能是两个用户 A (Spree::Gest ) 和 B (Spree::Reader) 具有相同的电子邮件地址但类型不同,我怀疑是设计或 spree_auth_devise 不识别哪个用户必须考虑进行身份验证,我认为将考虑第一个(如果首先找到用户 A,则不会考虑 B 进行身份验证,以防我想要登录的用户)。也许此功能需要覆盖创建操作或其他设计方法? ——
    • 嗨@Moh,我相信这超出了该问题的范围,这是另一个问题。无论如何,如果您有重复的电子邮件,那么您必须获得一些独特的价值,例如登录或其他。你可以这样配置:github.com/plataformatec/devise/wiki/…
    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多