【Ruby on Rails】Twitterログイン機能のつくりかた(gem omniauth-twitter)

Ruby on RailsのTwitter認証機能のつくりかた

こんにちは、いけあつです。

最近のWebサービスでよく見かける「Twitter認証機能」のつくりかたを調べて実装してみました。

今後も自作Webサービスをつくるときに利用することが多そうなので忘備録的に書いておきたいとます。

今回使用した開発環境は以下の通りです。

【ローカル開発環境】
・AWS Cloud9
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux] 
・Rails 5.2.3

この記事では下記動画のTwitter認証機能のつくりかたを解説します。

【この記事でつくる機能】
1. Twitter 認証画面を表示する
2. 「login」 をクリックすると Twitter 認証される
3. 認証後のページに遷移
4. 「logout」 をクリックするとログアウトする(1に戻る)

Twitter Developer アカウントを作成する

TwitterのAPIを使用して開発するためには、まずはじめにTwitter Developer サイトへアクセスしてアカウントを作成します。

TwitterのAPI_KEYとAPI_SECRETを取得する

つぎにTwitter Developer サイトにて自身のWebサービスを登録して、TwitterのAPI_KEYとAPI_SECRETを取得します。

いくつか英作文をしなければならないので「うっ、、、」となりますが、がんばりましょう。

(※API_KEYとAPI_SECRETは絶対に第三者に知られないよう取り扱ってください!悪い人にバレるといろんな個人情報が抜き取られて悪用されてしまいます!)

まずは、自分のアカウント名のプルダウンリストから「Apps」をクリックします。

TwitterのAPI_KEYとAPI_SECRETを取得する手順1

開いたページで「Create an app」をクリック

TwitterのAPI_KEYとAPI_SECRETを取得する手順2

「(required)必須」の欄をすべて記入していきます。

とくに重要な項目は下記の5つです。

App name:
Twitter Applicationの名前(自分のwebサービス名にしておくと便利)

Application description:
アプリケーションの説明

Website URL:
自分のwebサービスのURL

Callback URLs:
Twitter認証後に遷移するURL。2つ以上指定しないとエラーが発生

Enable Sign in with Twitter:
Twitter認証を使用できるようにするかどうか。チェックボックスをONにする

ぼくの場合「Website URL」と「Callback URLs」の指定が正しくできていなくてエラーが発生しました。

【いけあつのローカル開発環境での正しい設定】
Website URL:
https://a41d53b851cd46c79dc17dd37e91cda7.vfs.cloud9.ap-northeast-1.amazonaws.com/auth/twitter

Callback URLs 1:
http://127.0.0.1:3000/auth/twitter/callback

Callback URLs 2:
https://a41d53b851cd46c79dc17dd37e91cda7.vfs.cloud9.ap-northeast-1.amazonaws.com/auth/twitter/callback

「/auth/twitter」の前の部分(太字)は自身の開発環境に合わせて指定する必要があります。

コピペしてもエラーになるのでご注意を。

TwitterのAPI_KEYとAPI_SECRETを取得する手順3
TwitterのAPI_KEYとAPI_SECRETを取得する手順4

無事、登録ができたらアプリケーション名の右にある「Details」をクリックして、コードを書く上で必要な情報を確認しましょう。

TwitterのAPI_KEYとAPI_SECRETを取得する手順5

「App details」のページで「Sign in with Twitter」が「Enable」になっていることを確認できたら、「Key and tokens」をクリック。

TwitterのAPI_KEYとAPI_SECRETを取得する手順6

この「Key and tokens」のページに書かれている情報は絶対に第三者に知られないよう取り扱ってください!悪い人にバレるといろんな個人情報が抜き取られて悪用されてしまいます!

TwitterのAPI_KEYとAPI_SECRETを取得する手順7

これでひとまず、Twitter認証機能のコードを書くための準備は完了です!

Twitter 認証機能を実装する

ここからは Ruby on Rails でTwitter 認証機能のコードを書いていきます。

まずは、ターミナルにコマンドを打ち込んでRailsアプリケーションを作成しましょう。

$ rails new rails-auth-app

「GitHub に公開したくない情報」をpushしない設定をする

API_KEYとAPI_SECRET を使用して機能を実装していく前に、GitHub にpushしても特定の情報だけは公開されない設定をしておきます。

ことのき環境変数を使用します。

まずは、環境変数を使うための gem 「dotenv」 をインストールしましょう。

「Gemfile」のループ以外の場所に下記を追加します。

gem 'dotenv-rails'

記述したら「bundle install」します。

$ bundle install

つぎに環境変数を定義します。

「.env」というファイルを「Gemfile」などが置かれているディレクトリに作成して、下記を記述します。

TWITTER_CONSUMER_KEY='ここに API key を記述'
TWITTER_SECRET_KEY='ここに API secret key を記述'

GitHubにpushしたくないファイルは「gitignore」に記載してあげます。

下記を追記します。

# Ignore .evv files.
/.env

これで「GitHub に公開したくない情報」をpushしない設定ができました!

omniauth-twitterの設定を行う

「omniauth-twitter」はTwitter認証機能を簡単に実装するためのgemです。

先ほどと同様に「Gemfile」のループ以外の場所に下記を追加します。

gem 'omniauth-twitter'
gem "omniauth-rails_csrf_protection"

記述したら「bundle install」しましょう。

$ bundle install

つぎに、「omniauth.rb」というファイルを「config/initializers」のディレクトリに作成し、下記を記述します。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_SECRET_KEY']
end

これで「omniauth-twitter」の設定は完了です。

Model、View と Controller をつくる

まずは、Twitter認証後に得られるユーザーの情報を格納するuserモデルを制作します。

rails g model User provider:string uid:string nickname:string name:string image_url:string description:string

モデルを作成したら、データベースのマイグレートを忘れずに。

rails db:migrate

作成されたuserモデルを下記のように編集します。

class User < ApplicationRecord
  def self.find_or_create_from_auth(auth)
    provider = auth[:provider]
    uid = auth[:uid]
    nickname = auth[:info][:nickname]
    name = auth[:info][:name]
    image_url = auth[:info][:image]
    description = auth[:info][:description]
    
    self.find_or_create_by(provider: provider, uid: uid) do |user|
      user.nickname = nickname
      user.name = name
      user.image_url = image_url
      user.description = description
    end
  end
end

つぎに「ログイン」と「ログアウト」をするための「SessionsController」を作成しましょう。

$ rails g controller Sessions

「sessions_controller.rb」を下記のように編集します。

class SessionsController < ApplicationController

  def create
    user = User.find_or_create_from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.id
    redirect_to root_path
  end

  def destroy
    reset_session
    redirect_to root_path
  end  
  
end

つぎに、Twitter認証前後のページを作成するために「HomesController」を作成します。

$ rails g controller Homes
class HomesController < ApplicationController
  def index
    if session[:user_id].nil?
      redirect_to action:'login'
    else
      @user = User.find(session[:user_id])
    end
  end
  
  def login
  end
end

そして下記の2つのViewファイルを「/rails-auth-app/app/views/homes」ディレクトリ内に作成します。

①「login」ボタンがあるページ。

<%= link_to "login" ,"/auth/twitter", method: :post %>

②ユーザーのTwitter IDやプロフィールをテキストで表示するページ。「logout」ボタンがある。

<h1>Twitter連携</h1>
<p><%= "name:" + @user[:nickname]%></p>
<p><%= "screen_name:" + @user[:name]%></p>
<p><%= "image_url:" + @user[:image_url]%></p>
<p><%= "description:" + @user[:description]%></p>
<%= link_to "logout" ,:controller => "sessions", :action => "destroy" %>

最後にルーティングを設定して完成です!

Rails.application.routes.draw do
  root 'homes#index'
  get '/homes', to: 'homes#index'
  get '/auth/:provider/callback', to: 'sessions#create'
  get '/logout', to: 'sessions#destroy'
  get '/login', to: 'homes#login'
end

サーバーを起動して、この記事冒頭の動画のような動作が確認できたらOKです!

まとめ

ここまで読んでいただきありがとうございます!

Ruby on Rails で gem「omniauth-twitter」を使用したTwitter認証機能のつくりかたを忘備録的に解説しました。

Twitter Developer アカウントの作成から始まり、エラーの対処や脆弱性の改善など、調べながらコードを書いて正味8時間くらいかかったと思います。。。

自分を含め、今後自作のwebサービスを作ってTwitter認証機能を実装したい人の一助となったら幸いです!

「もっと簡単な方法あるよー」「ここ改善しないとセキュリティー危ないよ」などアドバイスございましたらコメントいただけると嬉しいです。

最後に参考にさせていただいた記事と作成したプログラムのソースコードを紹介します。

参考にさせていただいた記事

Ruby on RailsでTwitter認証機能を実装してみる(Reasonable Code)

【Ruby on Rails】GitHubに公開したくない変数や値を隠してpushする方法(Qiita @noraworld)

[Rails]gem “OmniAuth” の脆弱性対策(Qiita @NT90957869)

Rails5でOmniAuthを使ったTwitter連携(認証編) (ls -al)

今回作成したプログラムのソースコード

GitHub ikat-de/rails-auth-app