使用单独的身份验证模型设计on Rails的(Use separate authentication

2019-08-16 17:05发布

我有一个简单的解决方案,我用下面的对象自己做:

  • 账户 (已标记字段,即身份验证时,返回和API调用)
  • 验证 (有AUTH_TYPE / AUTH_ID和参考账户)

我有一个单独的认证模式,能够连接登录的几种方法(设备UUID,电子邮件/密码的Twitter,Facebook等)。 但似乎在设计的所有例子,你使用它的用户客户 )的模式。

是不是不够灵活? 例如OmniAuth模块存储供应商和ID的用户模型,如果你希望能够从Twitter和Facebook的登录会发生什么,只有一个供应商的房间吗?

我应该在我的账户模型或身份验证模型中使用设计?

Answer 1:

最近已着手在那里我是用设计来保持用户的令牌不同的服务项目。 有点不同的情况,但还是你的问题让我思考了一会儿。

我想结合制定反正账户模式。 为什么? 让我们来看看。

由于我的电子邮件是能够识别我作为一个用户的唯一的事情(和你提到的帐户作为用户),我将它放在accounts表中对与密码,这样我最初也能使用基本电子邮件/密码认证。 此外,我会保持API的令牌authentications

正如你所提到的,OmniAuth模块需要存储供应商和id。 如果你希望你的用户能够在同一时间(由于某种原因你这样做)提供不同的服务连接那么显然你需要保留两个提供商ID对某个地方,否则人会简单地将每一次覆盖单个用户验证。 这使我们的认证模式,即已经适用于和具有参考账户

因此,寻找一个供应商-ID对时要检查authentications表,而不是accounts 。 如果找到一个,你只需返回一个account与它相关联。 如果没有,那么你检查是否包含帐户,例如电子邮件的存在。 创建新authentication ,如果答案是肯定的,否则,创建一个,然后创建authentication它。

更具体:

#callbacks_controller.rb
controller Callbacks < Devise::OmniauthCallbacksContoller
  def omniauth_callback
    auth = request.env['omniauth.auth']
    authentication =  Authentication.where(provider: auth.prodiver, uid: auth.uid).first
    if authentication
      @account = authentication.account
    else
      @account = Account.where(email: auth.info.email).first
      if @account
        @account.authentication.create(provider: auth.provider, uid: auth.uid,
         token: auth.credentials[:token], secret: auth.credentials[:secret])
      else
        @account = Account.create(email: auth.info.email, password: Devise.friendly_token[0,20])
        @account.authentication.create(provider: auth.provider, uid: auth.uid,
         token: auth.credentials[:token], secret: auth.credentials[:secret])
      end
    end
    sign_in_and_redirect @account, :event => :authentication
  end
end

#authentication.rb
class Authentication < ActiveRecord::Base
  attr_accessible :provider, :uid, :token, :secret, :account_id
  belongs_to :account
end

#account.rb
class Account < ActiveRecord::Base
  devise :database_authenticatable
  attr_accessible :email, :password
  has_many :authentications
end

#routes.rb
devise_for :accounts, controllers: { omniauth_callbacks: 'callbacks' }
devise_scope :accounts do
  get 'auth/:provider/callback' => 'callbacks#omniauth_callback'
end

这应该给你你需要什么,同时保持所需的灵活性。



Answer 2:

您可以分离所有常见的逻辑模块,并使用唯一的同桌。

module UserMethods
  #...
end

class User < ActiveRecord::Base
  include UserMethods
  devise ...

end  

class Admin < ActiveRecord::Base
  include UserMethods
  self.table_name = "users"
  devise ...
end

而在航线分别配置所有色器件模型,视图(如果必要的话,请参阅配置查看)。 在这种情况下,您可以轻松地处理所有不同的逻辑。

还要注意的是,如果你在一个信念,即制定仅供用户模式,那么你就错了。

对于前。 - rails g devise Admin

这将为管理模式色器件。

更多信息这里 。



文章来源: Use separate authentication model with Devise on Rails