5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Twitter認証を使って二つのモデルでログインする際の注意(OmniAuth+devise)

Last updated at Posted at 2019-05-21

deviseを複数のモデルでのTwitter認証を実装しようとすると、うまくいかない。
自分は開発中のuserモデルとartistモデルがあるケースでつまったのでまとめていきます。

twitterapiの設定

Twitterのdeveloperアカウントは2018年の秋頃からしようが変更になり、英語でサービスがどのように使われるかを明示しなければならなくなりました。
https://qiita.com/tdkn/items/521686c240b0c5bc6207
承認されない時は、twitter社からメールが届き、いくつかの質問がされます。自分は2回ほどのメールのやり取りを経て、やっとアカウントが承認されました。(サービスをもっと具体的に教えろなど...)

APIKEYを設定してdeviseとomniauthの設定

gem 'devise'
gem 'omniauth-twitter'

を入れて、

下の記事のようにdeviseの設定とomniauthの設定をします
https://qiita.com/daigou26/items/d84e64af775a3054e950

複数モデルに適用させる

問題はここからです。omniauth+deviseだと複数モデルの時に適用されないのです。
実は公式のドキュメントに、

現時点では、DeviseのOmniauthableモジュールはそのままでは1つのモデルでしか利用できません。しかしご安心ください。
OmniauthableはOmniAuthの単純なラッパーにすぎないので、方法はあります。

と、記載があります。
手順にそって、複数modelにおいてもsns認証ができるようにしていきましょう。

1. deviseにおいてomniauthを使わない。

まず、userとartistのcontrollerにある

devise :omniauthable

を削除します。

2.ルーティング作成

また、routes.rbに、

get "/auth/twitter/callback" => "omniauth_callbacks#twitter"
get '/auth/another/twitter/callback' => 'anothers#twitter'

と記述し、deviseを使わずにそれぞれのルーティングを作成します。

3. controller設定

次にcontrollers/omniauth_callbacks.rbというコントローラーを作成し、
次にcontrollers/omniauth_callbacks__controller.rbというコントローラーを作成し、

class OmniauthCallbacksController < ApplicationController
  def twitter
    callback_from :twitter
  end

  def failure
    @notice = "failure"
    redirect_to events_path, notice: 'failure'
  end


  private

  def callback_from(provider)
    provider = provider.to_s

    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      print("persisted true")
      @notice = "persisted true"
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      print("persisted false")
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      @notice = "user is not persisted."
      redirect_to root_path, notice: 'user is not persisted.'
    end
  end
end

と記述します。
次に別のanothers_controller.rbというコントローラーを作成し、

class AnothersController < ApplicationController
  def twitter
    callback_from :twitter
  end

  def failure
    @notice = "failure"
    redirect_to events_path, notice: 'failure'
  end


  private

  def callback_from(provider)
    provider = provider.to_s

    @artist = Artist.find_for_oauth2(request.env['omniauth.auth'])

    if @artist.persisted?
      print("persisted true")
      @notice = "persisted true"
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @artist, event: :authentication
    else
      print("persisted false")
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      @notice = "user is not persisted."
      redirect_to root_path, notice: 'user is not persisted.'
    end
  end
end

とし、別のモデルからの設定をします。

4.プロバイダ作成

二つのルーティングができるようにプロバイダを変更します。

config/initializers/omniauth.rb

OmniAuth.config.full_host = "https://hogehoge.com" 
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'],info_fields:"nickname, image", request_path: '/auth/twitter', callback_path: '/auth/twitter/callback'
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'],info_fields:"nickname, image", request_path: '/auth/another/twitter', callback_path: '/auth/another/twitter/callback'
end

5.viewの設定

これで、

<%= link_to 'twitterでログイン', '/auth/twitter', :id => "twitter" %>
<%= link_to 'twitterでログイン', '/auth/another/twitter', :id => "twitter" %>

と記述すると、無事ルーティングされます。

参考記事

5
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?