MyFirstRails

Twitterログイン サンプル

概要

Railsにこれから初めて触れる方を対象にしたチュートリアルです RailsにTwitterでのログイン機能を実装するチュートリアルになります

チュートリアル

アプリのひな型を作る

まず、rails newを実行し、アプリのひな型を作成します

rails new twitter_login

次に、作成したアプリのディレクトリへと移動します

cd twitter_login

Deviseの導入

Twitterでのログイン機能を実装するにあたって、Deviseを使用します まず、Gemfilegem 'devise'を追加してbundle installを実行します

gem 'devise'
bundle install

この時、sqlite3がインストールできないエラーが発生するかもしれません その場合は以下のようにsqlite3のバージョンを修正してbundle installを実行してください

gem 'sqlite3', '1.3.13'
bundle install

bundle install後、以下のコマンドを実行してDeviseをインストールします

rails g devise:install
``

次に、`Devise`で使用する`View`ファイルを作成します

```shell
rails g devise:views

そして、Deviseで使用するModelを作成し、マイグレーションを実行します

rails g devise user
rails db:migrate

これでDeviseの導入は完了です!

Twitetrにアプリを作成

Twitterでのログインを実装するためには、Twitterへアプリケーションの登録が必要になります

こちらでアプリケーションを作成します

作成手順は以下の記事が参考になります

Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2018年9月時点の情報

アプリケーション作成後、API keyAPI secret keyを取得しておきます また、callback urlhttp://localhost:3000/users/auth/twitter/callbackと追加し、 Allow this application to be used to Sign in with Twitterにチェックをいれておきます

Dotenvの導入

Twitetrから取得したAPI keyAPI secret keyをソースコードにそのまま貼り付けてしまうと悪意のある第三者に利用されてしまう可能性があります 実際に、発生した事例としては以下のようなものがあります

AWSが不正利用され300万円の請求が届いてから免除までの一部始終

Peing脆弱性案件に見る初動のまずさ

こういったことを回避するためにもDotenvなどを使用してソースコードに直接書かないようにする必要があります

まず、Gemfilegem 'dotenv-rails'を追加します

gem 'dotenv-rails'

その後、bundle installを実行します

bundle install

そして、先ほど取得したキーなどを.envに書き込みます .envGemfileと同じ位置に作成します

# Using Twitter API
TWITTER_API_KEY=API key
TWITTER_SECRET_KEY=API secret key

最後に、.gitignoreを編集し、.envGitの管理対象から外します

# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore uploaded files in development
/storage/*
!/storage/.keep

/node_modules
/yarn-error.log

/public/assets
.byebug_history

# Ignore master key for decrypting credentials and more.
/config/master.key
.env

これでDotenvの導入は完了です!

Twitterログインの実装

Twitterアカウントでのログイン機能はOauthという認証を使用します

まず、必要なgemGemfileに追加します

gem 'omniauth'
gem 'omniauth-twitter'

bundle installgemをインストールします

bundle install

次に、Userモデルにカラムを追加してマイグレーションを行います

rails g migration AddColumnsToUsers uid:string provider:string
rails db:migrate

次に、config/initializers/devise.rbを編集してDevise側の設定を変更します

Devise.setup do |config|

  #<省略>

  # ==> OmniAuth
  # Add a new OmniAuth provider. Check the wiki for more information on setting
  # up on your models and hooks.
  # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'

  config.omniauth :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_SECRET_KEY']

 #<以下省略>
end

Dotenv経由でTwitterのAPIキーなどを読み取っています

次に、userモデルに:omniauthableを追加します

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :omniauthable
end

その後、self.find_for_oauth(auth)というメソッドを追加します

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :omniauthable

  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]
      )
      user.save!
    end
    current_user = user
  end
      
  private
      
    def self.dummy_email(auth)
      "#{auth.uid}-#{auth.provider}@example.com"
    end
end

このメソッドにより、アカウントが既に作成されているかをチェックし、アカウントがない場合は新しく作成することができるようになります

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] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

最後に、config/routes.rbにコールバック先のルーティングを追加します

Rails.application.routes.draw do
  devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
end

これでTwitterでのログイン機能は実装できました!

静的なページの作成

最後に、Twitterログインが実際に機能しているかどうかを確認するためのページを作成します

rails g controller web index

app/views/web/index.html.erbにTwitterログインのリンクなどを追加します

<h1>Web#index</h1>
<p>Find me in app/views/web/index.html.erb</p>

<%= link_to 'Twitter Login', user_twitter_omniauth_authorize_path %>

<% if user_signed_in? %>
    Your Welcome!
<% end %>

Twitter Loginをクリックしてログインできるようになっています また、ログインするとYour Welcome!の文字が画面に表示されるようになっています

実際にログインしてみよう

rails sでローカルサーバを起動し、localhost:3000にアクセスします

その後、Twitter LoginのリンクをクリックするとTwitterのアプリ認証の画面が表示されます

認証後、localhost:3000Your Welcome!と表示されていればOKです!