最近、さまざまなサービスのユーザートークンを保持するためにDeviseを使用していたプロジェクトに取り組んでいます。少し違うケースですが、それでもあなたの質問は私にしばらく考えさせました。
とにかく、Deviseをアカウントモデルにバインドします。なんで?どれどれ。
私の電子メールは私をユーザーとして識別できる唯一のものであるため(そしてあなたはアカウントをユーザーと呼びます)、私はそれをaccounts
パスワードと組み合わせてテーブルに配置し、最初は基本的な電子メール/パスワード認証を使用できるようにします。また、APIトークンをに保持しますauthentications
。
あなたが述べたように、OmniAuthモジュールはプロバイダーとIDを保存する必要があります。ユーザーが同時に異なるサービスに接続できるようにしたい場合(そして何らかの理由で接続できるようにする場合)、明らかに両方のプロバイダーIDペアをどこかに保持する必要があります。そうしないと、1人のユーザーが1人のユーザーごとに1つが上書きされるだけです。認証します。これにより、すでにそれに適していて、アカウントへの参照がある認証モデルにつながります。
したがって、プロバイダーと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
それはあなたが望む柔軟性を保ちながらあなたが必要とするものをあなたに与えるはずです。