【Rails】TwitterやFacebookで簡単ログインを実装
10分目次
当記事は旧サイトで2019/08/27に執筆したものを転載したものです。情報が古い可能性があります。
手順を自分用にメモがてら。deviseとomniauthを利用した簡単ログイン(Sign up)の実装方法です。以下gifは以前RailsでWebアプリ作った際の実装例です。
なお、この記事ではdeviseの導入からの手順を想定しています。ちなみに最近知りましたがFirebaseだとこういったSNSログインの実装が相当楽らしいですね。
環境
- Rails 5.2.3
- devise 4.7.0
- omniauth 1.9.0
- omniauth-twitter 1.4.0 公式ドキュメント
- omniauth-facebook 5.0.0 公式ドキュメント
手順1🚚 必要なGemの追加
Gemfileに以下5つのgemを追加して
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.0'
gem 'rails', '~> 5.2.3'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
(中略)
gem 'devise' #追加
gem 'omniauth' #追加
gem 'omniauth-twitter' #追加
gem 'omniauth-facebook' #追加
gem 'dotenv-rails' #追加
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
(略)
ターミナルにて下記コマンドでインストールします。
$ bundle install
手順2🚚 deviseのセットアップ
よくある普通の手順です。
$ rails g devise:install
$ rails g devise:views
$ rails g devise User
$ rails db:migrate
$ rails g devise:install
すると、下記のようなコメントが出てきていくつかのファイルが生成されます。
Running via Spring preloader in process 43388
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
上のコメントの数字の振られた手順を順番に実装していくとdeviseの使用が可能になります。まずは1からです。config/environments/development.rbの最後に1行を追加します。
(中略)
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
次にターミナルにて下記のコマンドを実行します。
$ rails g controller home index
すると、app/controllersディレクトリにhome_controller.rbとapp/viewsディレクトリにhomeディレクトリとその階層内にindex.html.erbができます。
次に2。config/routes.rbを開き、下記のようにします。
Rails.application.routes.draw do
root "home#index" #追加
(中略)
end
3ではapp/views/layouts/application.html.erbに下記のようにします。
(中略)
<body>
<!-- ここから追加 -->
<% if flash[:notice] %>
<p><%= flash[:notice] %></p>
<% end %>
<% if flash[:alert] %>
<p><%= flash[:alert] %></p>
<% end %>
<!-- ここまで追加 -->
<%= yield %>
</body>
そして4のコマンドとモデルの作成のためのコマンドを上から順にターミナルで実行すればdeviseの実装は完了です。
$ rails g devise:views
$ rails g devise User
$ rails db:migrate
ユーザー登録のストロングパラメータ周り
app/controllers/application_controller.rbを下記のようにします。
class ApplicationController < ActionController::Base
(中略)
#ここから追加
before_action :configure_permitted_parameters, if: :devise_controller?
protected
#登録時と編集時に独自カラムのストロングパラメータ追加
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: %i(name uid image provider))
devise_parameter_sanitizer.permit(:account_update, keys: %i(name uid image provider))
end
#ここまで追加
end
deviseの日本語化
config/application.rbを下記のように編集します。
require 'rails/all'
Bundler.require(*Rails.groups)
module Config
class Application < Rails::Application
config.load_defaults 5.2
(中略)
#ここから追加
config.i18n.default_locale = :ja #日本語化する
config.time_zone = 'Asia/Tokyo' #タイムゾーンを日本時間にする
#ここまで追加
end
end
続いてconfig/localesディレクトリにja.ymlを新規作成し、下記をコピペしてください。
ja:
activerecord:
models: #モデル名の日本語化
user: "ユーザー"
attributes:
user: #ユーザーモデルのカラム名日本語化
name: "名前"
uid: "ID"
image: "プロフィール画像"
email: "メールアドレス"
password: "パスワード"
devise: #deviseに関するエラーメッセージ等の日本語化
confirmations:
confirmed: "アカウントが正常に確認されました。"
send_instructions: "アカウントの確認方法をメールにてお送りします。"
send_paranoid_instructions: "すでにメールアドレスが保存されている場合、アカウントの確認方法をメールにてお送りします。"
failure:
already_authenticated: "ログイン済みです。"
inactive: "まだアカウントが有効化されていません。"
invalid: "メールアドレスまたはパスワードが違います。ご確認ください。"
locked: "このアカウントはロックされています。"
last_attempt: "あなたのアカウントがロックされる前に、もう1つの試みを持っています。"
not_found_in_database: "メールアドレスまたはパスワードが無効なものです。ご確認ください。"
timeout: "一定時間が経過したため、再度ログインが必要です"
unauthenticated: "ログインまたは登録が必要です。"
unconfirmed: "本登録が必要です。"
mailer:
confirmation_instructions:
subject: "アカウントの登録方法"
reset_password_instructions:
subject: "パスワードの再設定"
unlock_instructions:
subject: "アカウントのロック解除"
omniauth_callbacks:
failure: "%{reason}により、%{kind}から承認されませんでした。"
success: "%{kind}から承認されました。"
passwords:
no_token: "このページにアクセスできません。URLをご確認ください。"
send_instructions: "パスワードのリセット方法をメールにてお送りします。"
send_paranoid_instructions: "すでにメールアドレスが保存されている場合、パスワードの再設定方法をメールにてお送りします。"
updated: "パスワードを変更しました。"
updated_not_active: "パスワードを変更しました。"
registrations:
destroyed: "アカウントを削除しました。またのご利用をお待ちしております。"
signed_up: "アカウント登録を受け付けました。"
signed_up_but_inactive: "アカウントは登録済みですが、有効化されていないため利用できません。"
signed_up_but_locked: "アカウントは登録済みですが、ロックされているため利用できません。"
signed_up_but_unconfirmed: "確認メールを登録したメールアドレス宛に送信しました。リンクを開いてアカウントを有効化してください。"
update_needs_confirmation: "アカウント情報が更新されました。更新の確認メールを新しいメールアドレス宛に送信しましたので、リンクを開いて更新を有効化してください。"
updated: "アカウントが更新されました。"
sessions:
signed_in: "ログインしました。"
signed_out: "ログアウトしました。"
Invalid email or password: "メールアドレスまたはパスワードが違います"
unlocks:
send_instructions: "アカウントのロック解除方法をメールにてお送りします。"
send_paranoid_instructions: "アカウントが存在する場合、ロックの解除方法をメールにてお送りします。"
unlocked: "アカウントのロックが解除されました。ログインしています。"
errors:
messages:
already_confirmed: "は既に登録済みです。ログインしてください"
confirmation_period_expired: "%{period}以内に確認する必要がありますので、新しくリクエストしてください。"
expired: "有効期限切れです。新規登録してください。"
not_found: "は見つかりませんでした。"
not_locked: "ロックされていません。"
not_saved:
one: "以下のエラーで、この%{resource}を保存できません。"
other: "%{count}個のエラーで、%{resource}を保存できません。"
モデルに追記
app/models/user.rbのdeviseに:omniauthable
を追加し、find
メソッドを追記します。
class User < ApplicationRecord
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.nickname,
name: auth.info.name,
image: auth.info.image,
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
手順3🚚 omniauthのセットアップ
deviseはデフォルトではメールアドレスとパスワード用カラムしかなく、このままだとうまく動作しないのでターミナルにてUsersテーブルにカラムを追加します。
$ rails g migration AddColumnsToUsers name:string uid:string image:string provider:string
$ rails db:migrate
これでTwitterやFacebookから得た名前や画像などをデータベースへと格納できるようになります。続いて、config/initializers/devise.rbを下記のようにします。
Devise.setup do |config|
(中略)
config.omniauth :facebook, ENV['FACEBOOK_ID'], ENV['FACEBOOK_SECRET'],
{
:secure_image_url => 'true',
:image_size => 'large'
}
config.omniauth :twitter, ENV['TWITTER_ID'], ENV['TWITTER_SECRET'],
{
:secure_image_url => 'true',
:image_size => 'original'
}
end
ここまで出来たら下記URLにアクセスし、各SNSのAPIキーを取得します。
https://developers.facebook.com/ https://developer.twitter.com/
次に.envファイルを新規作成し、下記のようにします。
TWITTER_ID: 'ここにTwitterのAPIキーをコピペ'
TWITTER_SECRET: 'ここにTwitterのシークレットキーをコピペ'
FB_ID: 'ここにfacebookのAPIキーをコピペ'
FB_SECRET: 'ここにfacebookのシークレットキーをコピペ'
手順4🚚 コールバック処理の追加
app/controllersディレクトリにomniauthcallbackscontroller.rbを新規作成し、下記をコピペ。
class 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
手順5🚚 ルーティングを編集
config/routes.rbを下記のように編集。
Rails.application.routes.draw do
root "home#index"
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
(中略)
end
動作確認
ここまできたらターミナルにてrails s
を実行し、ローカルサーバーを立てて……
./users/sign_up/ にアクセスします。
試しにSign in with Twitterをクリックすると……
rootにリダイレクトされ、ログイン状態になりました。あとはcssでお化粧すればいい感じになりますね。