概要

Rails5系でdeviseomniauthを利用してtwitterログインの実装をテスト のメモ。

rubyのバージョン管理はrbenv
環境変数の管理にはdirenv 使ってます。
ファイル編集はVim

環境

macOSX
rails 5.1.5
ruby 2.5.0
rbenv
bundler
direnv
vim

参考

[Rails] deviseの使い方(rails5版)
https://github.com/tmk815/Twitter_OmniAuth <- ほぼこちらの模倣です

うまくいかないときに確認すべきファイル等

#(プロバイダ毎の)コールバック処理など
vim app/controllers/users/omniauth_callbacks_controller.rb
#deviseのモジュール設定や、ユーザー登録処理など(userのDBにカラム設定していないものは情報保存できないので注意)
vim app/models/user.rb
#ルーティング設定(OAuthコールバック処理)
vim config/routes.rb
#deviseでのAPIキー設定など(development.rbに記述する場合は不要かも?)
vim config/initializers/devise.rb
#ログイン済みか確認する処理
vim app/controllers/application_controller.rb 

準備

今回は例で
ワークスペース位置を~/Projects
プロジェクト名をdevise_omniauth_sample
としています。

cd ~/Projects
bundle init
echo -e "ruby '2.5.0'\ngem 'rails'" >> Gemfile
rbenv local 2.5.0
bundle install --path vendor/bundle
bundle exec rails new devise_omniauth_sample --skip-bundle

rm -f Gemfile Gemfile.lock | rm -rf .bundle vendor/bundle

#必要に応じて通常使用rubyの戻し指定
#rbenv local 2.0.0-p648
cd ~/Projects/devise_omniauth_sample
rbenv local 2.5.0
echo -e "gem 'devise'\ngem 'omniauth-twitter'" >> Gemfile
bundle install --path vendor/bundle
echo '/vendor/bundle' >> .gitignore

bundle exec rails g devise:install
bundle exec rails g controller Pages index show
bundle exec rails g devise:views
bundle exec rails g devise User
bundle exec rails g migration add_columns_to_users provider uid username

bundle exec rake db:migrate

構築

下記ファイルを編集していきます。

vim config/routes.rb
vim app/views/layouts/application.html.erb
vim app/models/user.rb
vim app/views/pages/index.html.erb
vim app/controllers/application_controller.rb

各項目の記述内容

ルーティング設定

ルートアクセス時の設定記述
devise_forの部分にコールバック時の設定を記述

config/routes.rb
  root 'pages#index'
  get 'pages/show'

  devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }

viewのレイアウト表示

ログイン・ログアウト等を表示させる

<body>直下に記述 ↓

app/views/layouts/application.html.erb
     <header>
         <nav>
             <% if user_signed_in? %>
             <strong><%= link_to current_user.username, pages_show_path %></strong>
             <%= link_to 'プロフィール変更', edit_user_registration_path %>
             <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
         <% else %>
             <%= link_to 'サインアップ', new_user_registration_path %>
             <%= link_to 'ログイン', new_user_session_path %>
             <% end %>
         </nav>
     </header>

     <p class="notice"><%= notice %></p>
     <p class="alert"><%= alert %></p>

ユーザー登録処理

deviseのモジュールに:omniauthableを追加(手前に , を忘れずに)
残りはend手前に記述 ↓

app/models/user.rb
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :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),
        username: auth.info.nickname,
        password: Devise.friendly_token[0, 20]
      )
    end

    user
  end

  private

  def self.dummy_email(auth)
    "#{auth.uid}-#{auth.provider}@example.com"
  end

表示されるviewファイル

内容はパク適当です。(適宜自由に編集)

app/views/pages/index.html.erb
<% if user_signed_in? %>
<h1>こんにちは、<%= current_user.username %>さん</h1>
<p>ユーザー用ページです。</p>
<% else %>
<p>ログインしてください</p>
<% end %>

ログインしているかチェックする設定

app/controllers/application_controller.rb
protect_from_forgery with: :exception
before_action :authenticate_user!

テスト用SNSアプリ設定(API等)

上記は用意済みの前提で以下の作業を進める

環境変数の設定

direnvのインストール

direnv設定

direnv edit .

上記で取得済みのAPIキー2種を記述する。

.envrc
export TWITTER_CONSUMER_KEY="twitterのAPIキー"
export TWITTER_CONSUMER_SECRET="twitterのAPI_Secretキー"

git管理から除外

echo '/.envrc' >> .gitignore

SNS認証処理用の設定

APIキー読込み設定

config/initializers/devise.rb
# ==> OmniAuth
#config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET']
  twitter_consumer_key = ENV['TWITTER_CONSUMER_KEY']
  twitter_consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
  config.omniauth :twitter, twitter_consumer_key, twitter_consumer_secret

コールバック用コントローラーの作成

bundle exec rails g controller users/omniauth_callbacks
vim app/controllers/users/omniauth_callbacks_controller.rb
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

確認

サーバー起動して

bundle exec rails s

http://localhost:3000/
にアクセスして「Twitterアカウントでログイン」できるか確認してみる。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.