技術系ブログ

とにかく小ネタで

【rails5.2】deviseを用いた、twitterログイン機能導入からherokuでの本番環境利用まで

twitterログイン機能を追加したので、やり方を残しておきます。
deviseを導入済みで勧めていきます。

TwitterAPIの取得

参考:Twitter Developerの開発者申請(例文あり)とAPIキー取得方法まとめ【2019年版】
これが今現在と一番変更点がない内容だと思います。 調べたらわかると思いますが、仕様が短期間に結構変わっているので参考にする記事の日付を確かめたほうが安全です。

twitterのアカウントの方にemailが登録されていない方は登録しないと進みません。
Callback URLについて、TwitterのAPIでcallbackURLをチェックするようになった - Qiita
Callback URLは複数登録でき、書き方も決まっているので気をつけてください。

#僕の場合
http://localhost:3000/users/auth/twitter/callback
http://自分のドメイン名.herokuapp.com/users/auth/twitter/callback
https://自分のドメイン名.herokuapp.com/users/auth/twitter/callback

参考: twitterログイン認証403で苦しんだ(Heroku) | makes-life-better

【Rails】deviseのTwitter認証で「Unauthorized 403 Forbidden」が出てしまう場合の対処法

Consumer API keysをrails側にsaveする

無事にAPIキーが取得できたら次はAPIキーが取得を保存します
ターミナルからEDITOR=vim rails credentials:editとして
iで書けるようになります。 書き方に注意してください。#コメントアウトを外すのと半角スペースをしっかり使うことです。
参考:「String does not have #dig method」AWS S3とのねちっこい戦い【初心者の場合】 - Qiita

 twitter:
    twitter_api_key:  API key
    twitter_api_secret_key:  API secret key

書けたらescボタンを押して:wqで saveされます。

gemの導入とmigration

gemの追加

#Gemfile
gem 'omniauth'
gem 'omniauth-twitter'

そしてbundle

参考:Devise+OmniAuthでユーザ認証を実装する手順 - Qiita

rails g migration AddColumnsToUsers uid:string provider:string
そしてrails db:migrate
参考:OmniAuth: Overview · plataformatec/devise Wiki · GitHub

devise側の編集

devise側にapiキーを書き込む

開発環境と、本番環境を分けています。

#config/initializers/devise.rb
# ==> OmniAuth
  if Rails.env.development?
    config.omniauth :twitter, Rails.application.credentials.dig(:twitter, :twitter_api_key), Rails.application.credentials.dig(:twitter, :twitter_api_secret_key), callback_url: "http://localhost:3000/users/auth/twitter/callback"
  elsif Rails.env.production?
    config.omniauth :twitter, Rails.application.credentials.dig(:twitter, :twitter_api_key), Rails.application.credentials.dig(:twitter, :twitter_api_secret_key), callback_url: "http://本番環境のURL/users/auth/twitter/callback"
  else
    config.omniauth :twitter, Rails.application.credentials.dig(:twitter, :twitter_api_key), Rails.application.credentials.dig(:twitter, :twitter_api_secret_key), callback_url: "http://localhost:3000/users/auth/twitter/callback"
  end

deviseメソッドの追加

:omniauthableを追加する

#app/models/user.rb
  devise :database_authenticatable, :registerable,
  :recoverable, :rememberable, :validatable,:omniauthable

Userモデルにfindメソッド追加

#app/modles/user.rb
  def self.find_for_oauth(auth)
    user = User.where(uid: auth.uid, provider: auth.provider).first

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

    user
  end

  private

  def self.get_email(auth)
    auth.info.email || "#{auth.uid}-#{auth.provider}@example.com"
  end
end

ここでの注意点は、メールアドレスはTwitterログインでは取得できないという点です。
なのでダミーを追加するようです。

Userコントローラにコールバック処理を実装

#app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitter
    callback_from :twitter
  end

  private

  def callback_from(provider)
    provider = provider.to_s

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

    if @user.persisted?
     flash[:notice] = "ログインしました。"
     sign_in_and_redirect @user, event: :authentication
    else
      redirect_to new_user_registration_path, alert: "ユーザー認証に失敗しました。"
    end
  end
end

persisted?とはActive Record object がDB に保存済みかどうかを判定するメソッド です。 最近知ったRailsの便利なメソッド

sign_in_and_redirectとは
deviseでOAuth認証後のログイン先を変更する方法 | 眠らないブログ
devise に関する routes まとめ - Qiita

ルーティング処理

#config/routes.rb
  devise_for :users, controllers: {
    omniauth_callbacks: "users/omniauth_callbacks",
  }

リンクを表示させる

私の場合

#app/views/devise/sessions/new.html.slim

 = link_to "twitterでログイン", user_twitter_omniauth_authorize_path

これで開発環境はうまくいくはずです。

heroku編

git push heroku
heroku run rails db:migrate
heroku restart

で本番環境もうまくいくはずです。 heroku logs -tでエラーを見ることもできます。
参考:OmniAuthのTwitterログインが、Herokuにデプロイしたらエラーになった - Qiita

Herokuが「ActiveRecord::UnknownAttributeError」を吐き出してプチハマりした話

OAuth::Unauthorized 401 Unauthorizedなんてエラーがでたら - Qiita

これで本番環境も大丈夫なはずです