Rails Ambassador

TwitterのOAuthでログイン機能を実装する

Twitterアカウントを持っていればパスワードなどを入力しなくてもログインできるOAuth認証の実装Tipsです。
Twitterアカウントを作成済みとします。

Railsアプリの作成とGit初期化

任意の名前でプロジェクトを作成しディレクトリの移動をおこなってください。
※このTipsではプロジェクト名をTwitterLoginとしています。

$ rails new TwitterLogin
$ cd TwitterLogin

Gitリポジトリも登録しておきましょう。

$ git init
$ git add .
$ git status
$ git commit -m "app init"

Herokuアプリの作成

TwitterAPIの申請にサイトURLが必要になるので先にherokuアプリを作っておきましょう。
URLの確認も行って控えておきましょう。

$ heroku create アプリ名
$ heroku info

TwitterAPIキーを取得

以下のリンクからアプリの登録を行ってください。

https://developer.twitter.com/

Callback URLは以下のように/auth/twitter/callbackにします。

https://アプリ名.herokuapp.com/auth/twitter/callback

OAuth認証を有効にするためEnable Sign in with Twitterにチェックを入れておきます。

Keys and tokensタブをクリックすると表示される API keyAPI secret keyを使いますので控えておきます。

Herokuの環境変数に取得したAPI情報を登録

ターミナルのアプリのディレクトリでHerokuの環境変数に取得したAPI keyとAPI secret keyを登録します。
※以下コマンドのスペース位置に注意しましょう。

$ heroku config:set TWITTER_API_KEY=取得したAPI key
$ heroku config:set TWITTER_API_SECRET=取得したAPI secret key

正しく環境変数がセットできたか確認

$ heroku config

ここまで問題が無ければアプリ作成に入りましょう。

Userモデルの作成

一般的によく使いそうなユーザー情報をDBに保存します。
※メールアドレスを取得するには別途申請が必要です。

$ rails g model User name nickname uid provider image

DB作成とマイグレーションを行います。
※必要に応じてインデックスを設定する方はマイグレーションを行う前に設定しておきましょう。

$ rails db:create
$ rails db:migrate

TOPページの作成

コントローラの設定

今回はTOPページにtwitter登録・ログインをつけていきます。
まずコントローラを作成しましょう。

$ rails g controller top index

ルートの設定

ルーティングの設定も行います。
config/routes.rb

Rails.application.routes.draw do
  root to: 'top#index'
  get '/auth/:provider/callback', to: 'sessions#create'
  post 'login', to: 'sessions#create' #ログイン用
  delete 'logout', to: 'sessions#destroy' #ログアウト用
end

get '/auth/:provider/callback', to: 'sessions#create'の行は認証後のコールバック用のルートになります。

Viewの作成

views/top/index.html.erb

<%= link_to "Twitterで登録・ログイン",  '/auth/twitter', class: 'btn btn-primary btn-sm' %>

表示の確認

サーバを起動してログインリンクがTOPページで表示されているか確認しておきましょう。

Gemの追加とログイン/ログアウトの実装

OAuth認証をするためのGemを追加します。

Gemfileの一番下に追加(※任意の場所でも良いですがproduction環境でインストールされるようにしてください。)
HerokuのデータベースはPostgreSQLなのでgem pgもインストールされるようにしておきます。(※PostgreSQLを使わない場合は不要です。)

gem 'omniauth'
gem 'omniauth-twitter'
gem 'pg', group: :production

記載したらインストールを行います。

$ bundle install

OminiAUTH用の設定を行う

config/initialzers/omniauth.rbを作成し以下のように記述を行ってください。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter,
  Rails.application.secrets.twitter_api_key,
  Rails.application.secrets.twitter_api_secret
end

config/secret.ymlを作成し以下のように記述を行ってください。

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  twitter_api_key: <%= ENV["TWITTER_API_KEY"] %>
  twitter_api_secret: <%= ENV["TWITTER_API_SECRET"] %>

SessionsControllerの作成

ログイン・ログアウト用のコントローラを作成します。

$ rails g controller sessions

controllers/sessions_controller.rb

class SessionsController < ApplicationController
  include SessionsHelper

  def create
    user = User.find_or_create_from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.id
    flash[:success] = 'ログインしました。'
    redirect_to root_url
  end

  def destroy
    session[:user_id] = nil
    flash[:success] = 'ログアウトしました。'
    redirect_to root_url
  end
end

ヘルパーにログイン用のメソッドを追加

app/helpers/sessions_helper.rb

module SessionsHelper
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !!current_user
  end
end

モデルの実装

find_or_create_from_authメソッドを追加します。 app/models/user.rb

class User < ApplicationRecord

  def self.find_or_create_from_auth(auth)
    provider = auth[:provider]
    uid = auth[:uid]
    name = auth[:info][:name]
    nickname = auth[:info][:nickname]
    image = auth[:info][:image]

    self.find_or_create_by(provider: provider, uid: uid) do |user|
      user.nickname = nickname
      user.image = image
      user.name = name
    end
  end

end

Viewにログアウトを追加

app/views/top/index.html.erb

<% if logged_in? %>
  こんにちは<%= current_user.name %>
<%= link_to 'ログアウト', logout_path, method: :delete %>
<%= current_user.nickname %> <%= image_tag(current_user.image) %> <% else %> <%= link_to "Twitterで登録・ログイン", '/auth/twitter', class: 'btn btn-primary btn-sm' %> <% end %>

Heroku用の設定をしデプロイ

Herokuで使うPostgreSQL用の設定を記述します。Productionの部分を変更します。

config/database.yml
※YAMLファイルのインデントは半角スペース2つです。注意してください。

production:
  adapter: postgresql
  pool: 5
  encoding: unicode
  database: #任意のDB名
  username: #任意のUser名
  password: <%= ENV['xxxx_DATABASE_PASSWORD'] %>

記載が終わりましたらコミットし、デプロイしましょう。

$ git add .
$ git status
$ git commit -m "Deploy to Heroku"
$ git push heroku master
$ heroku run rails db:migrate