2019.06.02
【Rails】Devise+OmniAuthでTwitter認証を実装する
RailsアプリにTwitter認証機能を実装する
今作成中のアプリでユーザの登録を簡易的にしたいと思い、実装に至ります。しかし、Devise+OmniAuthでの実装はパパっとできるかなと思ったんですが、CallbackのURLで引っかかったので解決経緯を纏めます。
またQiita参考サイトにそってやっていますが、足りない情報等自分なりに付け加えてます。
参考サイト
【Qiita】Devise+OmniAuthでユーザ認証を実装する手順
環境
Rails 5.2.3
devise 4.7.1
omniauth 1.9.0
カラムの追加について
上記参考サイトのまま進めるとuid(一意のID)とprovider(FacebookやTwitterなど)のみ追加しています。このままだとツイッター等でログインしたあとユーザーネームやプロフ画像を取得できないので必要な場合カラムを追加します。
$ rails g migration add_columns_to_users provider uid name nickname image
devise.rbの末尾に以下を追記。
config/initializers/devise.rb config.omniauth :twitter, ENV['TWITTER_ID'], ENV['TWITTER_APP_SECRET']
環境変数の設定(.env)
dotenvは環境変数を実行環境が異なっても使えるようになるものらしいです。
Gemfileと同じ階層に.envというファイルを作成。
$ touch .env
TwitterDevelopperに記載されているAPI keyとAPI secret keyを.envに記載。
.env
TWITTER_ID='API key'
TWITTER_APP_SECRET='API secret key'
最後にgitignoreファイルに.envを追加する。追加することでgitにアップされなくなります。
gitignore
/.env
TwitterDeveloperのcallback URLの指定について
上記参考サイトの記事(Qiita)のままやると自分の環境下だとコールバック処理の部分で以下エラーが出ました。
OAuth::Unauthorized 403 Forbidden
OAuth::Unauthorized 403 Forbidden が発生したらTwitterDeveloperでcallback URLを確認。
TwitterDeveloperのcallback URLの指定で、調べてみると「localhostで指定するとうまくいかない」という記事がいっぱいありましたが、自分の環境だとなぜかlocalhost指定しないとうまくいきませんでした。
例)localhost指定の場合
http://localhost:3000/users/auth/twitter/callback
例)IP指定の場合
http://127.0.0.1:3000/users/auth/twitter/callback
多分環境によって違うので、各々試してみてうまく動くほうをcallback URLに指定すればいいと思います。
"/users/auth/twitter/callback" の部分は
$ rails routes
で各々確認できます。
※黄色の下線部分を確認する↓↓
これでTwitter認証画面に遷移すると思ったんですが、またまた同じエラー発生。
TwitterDeveloperから取得したAPI keyを記載する場所に、callback URLを追記したらTwitter認証画面へ無事遷移しました。
config/initializers/devise.rb
config.omniauth :twitter, "API key", "secret key",
callback_url: 'http://localhost:3000/users/auth/twitter/callback'
viewのパス指定でエラー発生
リンクの下記パス指定するとエラーが発生。
user_omniauth_authorize_path(:twitter)
NoMethodError in Devise::Registrations#new
修正前
<%= link_to "Sign in with Twitter", user_omniauth_authorize_path(:twitter) %>
修正後
<%= link_to "Sign in with Twitter", user_twitter_omniauth_authorize_path %>
これでエラーはなくなり、認証画面に無事遷移しました。
エラー発生した時の確認するべきポイント
Deviseでログアウト時にエラー発生 確認ポイントその①
ログアウトしようとするとRouting Errorが出ました。
$rails routes で確認↓↓
HTTPメソッドをdeleteからgetに変更しないと動かないっぽいでdevise.rbを編集します。
config/initializers/devise.rb
config.sign_out_via = :get
編集後、サーバを再起動するとうまくログアウトできました。
Deviseでログアウト時にエラー発生 確認ポイントその②
layouts/application.html.erbの中にデフォルトで記載されているjavascriptのタグがあるか確認してください。
このタグがないとRouting Errorで一致するルートがありませんと表示されてしまいます。
layouts/application.html.erb
<%= javascript_include_tag 'application' %> #ない場合は追加
ログインのリンクを押下して今一度動きを確認
Twitter認証画面に遷移↓
無事ログイン完了!!
本番環境にデプロイしてみる
herokuにpushしてtwitter認証を試してみたところいつものエラー発生。
デプロイ後にエラー発生。原因その①
herokuに環境変数を設定していない
twitterのAPI key, API secret keyをherokuに追加。
herokuのsettingにあるConfig Varsからも追加できますが、コマンドでの方法も一応書いておきます。(自分用に笑)
$ heroku config:add API_KEY="your_twitter_api_key"
$ heroku config:add API_SECRET_KEY="your_twitter_api_secret"
デプロイ後にエラー発生。原因その②
TwitterDevelopperにて本番環境用のURLが記載されていない
原因はTwitter DeveloperのCallbackURLにheroku(本番環境のURL)のURLを追加していなかったためでした。
app detailsから本番環境のURLを追加したところ正常にtwitter認証に成功しました。
https://アプリ名.herokuapp.com/auth/twitter/callback
というわけで様々なエラーに苦しみながらも何とか実装できました。
千里の道も一歩から。とりあえず形になってよかった(;^^)
備考
deviseのViewの確認
$ rails g devise:views
・app/views/devise/sessions/new.html.erb ... ログイン
・app/views/devise/registrations/new.html.erb ... ユーザ登録
・app/views/devise/registrations/edit.html.erb ... ユーザ情報変更
環境変数の設定(.env)
環境変数を記載する時に必要なもの。
Gemfileにdotenvを追加、bundle install実行。
$ touch .env を実行し、ファイルを作成。ファイルの場所はGemfileと同じ階層に作成。
.envファイルにtwitter Developerにあるapi key、secret keyを記載。
.gitignoreに/.envを追加し、gitから除外させること。