【问题标题】:How do you add additional scoping to Devise user_signed_in? helper?您如何为设计 user_signed_in 添加额外的范围?帮手?
【发布时间】:2016-01-20 01:35:56
【问题描述】:

我的身份验证需要独立于:

subdomain1.domain.com subdomain2.domain.com 等等

现在使用设计 user_signed_in? 助手 - 如果有人在 subdomain1 上进行身份验证,它正在 subdomain2 上工作。我想添加一个tenant_id 范围来防止这种情况发生。

我已经能够在我的模型中使用以下方法对登录身份验证执行此操作:

def self.find_for_database_authentication(warden_conditions)
      where(:email => warden_conditions[:email], :tenant_id => warden_conditions[:tenant_id]).first
end

但我不清楚如何在已登录的支票上执行此操作。

谢谢!

【问题讨论】:

    标签: ruby-on-rails devise warden


    【解决方案1】:

    为此,您需要将身份验证范围缩小到子域。

    这是一个Docs 页面,介绍如何完成此操作。我会在此处添加以供参考:

    概述

    1. 修改设计生成的迁移以删除电子邮件唯一性约束索引
    2. 更改登录密钥以包含:subdomain
    3. 覆盖设计挂钩方法find_for_authentication

    修改迁移

    首先,您必须删除电子邮件索引唯一性约束。因为我们将把它变成一个范围查询,我们将把新索引的范围限定为子域。如果这是全新的 Devise 模型,您可以打开 Devise 迁移并更改以下内容:

    # db/migrate/XXX_devise_create_users.rb
    def change
      # Remove this line
      add_index :users, :email, :unique => true
    
      # Replace with
      add_index :users, [:email, :subdomain], :unique => true
    end
    

    如果这是一个现有项目,您需要创建一个新的迁移来删除旧索引并添加一个新索引:

    rails g migration reindex_users_by_email_and_subdomain
    
    
    # db/migrate/XXX_reindex_users_by_email_and_subdomain.rb
    def change
      remove_index :users, :email
      add_index :users, [:email, :subdomain], :unique => true
    end
    

    更改登录密钥

    在您的设计模型中,将:subdomain 添加到:request_keys。默认情况下,:request_keys 设置为 []

       # app/models/user.rb
    class User
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, request_keys: [:subdomain]
    end
    

    如果您有多个 Devise 模型并且您希望它们都具有相同的 :request_keys 配置,您可以在 config/initializers/devise.rb 中全局设置它

    config.request_keys = [:subdomain] # default value = []
    

    如果您还希望仍然能够使用不带子域的 URL 登录,:request_keys 还可以使用带有布尔值的哈希值来指示是否需要密钥。

    config.request_keys = { subdomain: false }
    

    检查您在模型的设计调用中没有:validatable

    如果您这样做, :validatable 将阻止多个记录具有相同的电子邮件,即使在不同的子域中也是如此。如果你想保留一些验证,你可以从https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb复制你想要的那些

    覆盖 Devise auth finder 挂钩

    对于 Authenticatable,Devise 使用钩子方法 Model.find_for_authentication。覆盖它以包含您的其他查询参数:

    # app/models/user.rb
    class User < ActiveRecord::Base
      def self.find_for_authentication(warden_conditions)
        where(:email => warden_conditions[:email], :subdomain => warden_conditions[:subdomain]).first
      end
    end
    

    恭喜,用户登录现在限定为子域!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 2013-05-23
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      相关资源
      最近更新 更多