deviseによるFacebook / Twitter 認証 -Rails奮闘記②-
本記事の紹介
本記事は、私がRuby on Rail(Rails, RoR)を用いたWebアプリケーションを作る過程を示したものです。 Railsの勉強も兼ねているため、間違いなどもあった場合はご指摘いただけると大変嬉しいです!
- OS: Mac OS 10.12.6
- Ruby: 2.5.0
- Ruby on Rails: 5.1.4
Devise を用いた基本的なユーザ認証の作成までは、過去記事を参照。
deviseによるOAuth 認証
Dotenvによる環境変数の管理
Gem: Dotenvを導入することでGitのリポジトリには含めずに外部APIの情報を環境変数として扱う。
1. Dotenvをインストール
# Gemfile gem 'dotenv-rails', require: 'dotenv/rails-now'
$ bundle install --path vendor/bundle
2. .env
ファイルを作成
# .env FB_APP_ID="[FacebookのアプリID]" FB_APP_SECRET="[Facebookのapp secret]" TW_APP_KEY="[TwitterのAPI key]" TW_APP_SECRET="[TwitterのAPI secret]"
3. コンソールを起動して、呼び出せるか確認
$ bundle exec rails c Running via Spring preloader in process 11075 Loading development environment (Rails 5.1.4) irb(main):001:0> Dotenv.load => {"FB_APP_ID"=>"[FacebookのアプリID]", "FB_APP_SECRET"=>"[Facebookのapp secret]", "TW_APP_KEY"=>"[TwitterのAPI key]", "TW_APP_SECRET"=>"[TwitterのAPI secret]"} irb(main):002:0> quit
4. .gitignore
に.env
を追加
/.env
Facebook / Twitter 認証の実装
5. Gemfileの編集
# Gemfile gem 'omniauth-facebook' gem 'omniauth-twitter'
6. インストール
$ bundle install --path vendor/bundle
7. OAuthで取得するproviderとuidを保持するために、Userモデルにカラムを追加
$ rails g migration add_columns_to_users provider uid $ rake db:migrate
8. Deviseにて取得したプロバイダの各キーを設定
Dotenvにて管理されている各キーをENV['HOSTNAME']
のように利用できる。
# config/initializers/devise.rb # (省略) # ==> 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 :facebook, ENV['FB_APP_ID'], ENV['FB_APP_SECRET'] config.omniauth :twitter, ENV['TW_APP_KEY'], ENV['TW_APP_SECRET'] # (省略)
9. Userモデルにモジュールを追加
# app/models/user.rb class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable # (省略) }
10. Userモデルにfindメソッドを実装
# app/models/user.rb class User < ApplicationRecord # (省略) 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.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end end
11. ディレクトリを作成
$ mkdir app/controllers/users
12. Userコントローラにコールバック処理を実装
# app/controllers/users/omniauth_callbacks_controller.rb class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def facebook callback_from :facebook end 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
13. ルーティング処理
# config/routes.rb Rails.application.routes.draw do devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } # (省略) end
まとめ
本記事は、以下の記事を参考にまとめました。