最近Googleログインの実装をやっていて、ついでにTwitterログインも実装しようとしたところ、躓いたのでメモしておきます。
TwitterAPI準備
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.id
とauth.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