与Devise on Rails一起使用单独的身份validation模型

我有一个简单的解决方案,我已经使用以下对象:

  • 帐户 (具有令牌字段,在API调用中进行身份validation和使用时返回)
  • 身份validation (具有auth_type / auth_id和对帐户的引用)

我有一个单独的身份validation模型,可以连接多种登录方式(设备UUID,电子邮件/密码,推特,脸书等)。 但似乎在Devise的所有示例中,您都在用户帐户 )模型上使用它。

这不是那么灵活吗? 例如,OmniAuth模块在User模型上存储提供者和ID,如果您希望能够从Twitter和Facebook登录,会发生什么?只有一个提供者的空间?

我应该在帐户模型或身份validation模型上使用Devise吗?

最近我正在开发一个项目,我正在使用Devise为不同的服务保留用户的令牌。 有点不同的情况,但你的问题仍让我想了一会儿。

无论如何,我会将Devise绑定到Account模型。 为什么? 让我们来看看。

由于我的电子邮件是唯一可以将我识别为用户的东西(并且您将帐户称为用户),我会将其与密码配对在accounts表中,以便我最初能够使用基本的电子邮件/密码认证。 我还会在authentications保留API令牌。

正如您所提到的,OmniAuth模块需要存储提供者和ID。 如果您希望您的用户能够同时连接不同的服务(并且出于某种原因),那么显然您需要将两个提供者ID对保留在某处,否则每次单个用户都会被覆盖validation。 这导致我们使用已经适合的身份validation模型,并引用了Account

因此,在查找提供者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 

这应该可以满足您的需求,同时保持您想要的灵活性。

您可以将所有常见逻辑分离到模块,并仅使用相同的表。

 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

这将为管理模型创建设计。

更多信息在这里 。