【Rails】omniauth-twitterでTwitterログインを実装する流れ


最近Googleログインの実装をやっていて、ついでにTwitterログインも実装しようとしたところ、躓いたのでメモしておきます。

TwitterAPI準備

Twitter Developers

Gemfile編集

Gemfile
gem 'omniauth'
gem 'omniauth-twitter'
gem 'devise'
gem 'dotenv-rails' #後で使う
$ bundle install
$ rails g devise:install
$ rails g devise user
$ rake db:migrate

devise.rbの編集

.env
TWITTER_ID='ペースト'
TWITTER_APP_SECRET='ペースト'
.gitignore
/.env
config/initializers/devise.rb
config.omniauth :twitter, ENV['TWITTER_ID'], ENV['TWITTER_APP_SECRET']

user.rb編集

user.rb
#以下を追記
protected
  def self.find_for_oauth(auth)
    user = User.where(uid: auth.uid, provider: auth.provider).first

    unless user
      user = User.create(name: auth.info.name,
                         email: User.dumy_email(auth),
                         provider: auth.provider,
                         uid: auth.uid,
                         password: Devise.friendly_token[0, 20]
                         )
    end
    user
  end

  private

  def self.dumy_email(auth)
    "#{auth.uid}-#{auth.provider}@example.com" #POINT
  end

上記のように作成されるUserについてはself.dumy_emailによってダミーのメールアドレスを生成するようにしています。ここではauth.idauth.providerの組み合わせが一意であることを利用しています。

Google/Facebookログインの実装では、email: auth.info.emailでメールアドレスを取得できたのですが、TwitterAPIではnilがかえってきてしまうため、上記のような実装が必要。

routes.rb編集

routes.rb
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }

omniauth_callbacks_controller.rb実装

app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def twitter
    callback_from :twitter
  end

  def callback_from(provider)
    provider = provider.to_s
    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: provider.capitalize
      sign_in_and_redirect @user, event: :authentication
      session[:user_id] = @user.id #add
    else
      session['devise.#{provider}_data'] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

ログインリンク実装

login_form.html.erb
<%= link_to 'Twitterログイン', user_twitter_omniauth_authorize_path  %>

Herokuデプロイでエラーが出る場合

以下の記事の後半で、Precompiling assets failedというエラーが出た際の対処法をかいていますので、よかったらどうぞ。

【Rails】Googleログイン実装〜Herokuデプロイまでの道のり

heroku run rails db:migrate前にやること!

今回はTwitterAPI情報を.gitignoreに指定しているので、Heroku側で設定する必要があります。

$ heroku config:set TWITTER_ID='ペースト'
$ heroku config:set TWITTER_APP_SECRET='ペースト'
$ heroku run rails db:migrate

参考リンク

Devise+OmniAuthでユーザ認証を実装する手順