Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[Rails] Facebook/Twitter/Googleでのユーザー登録をDevise & Omniauthを使って爆速で実装する

はじめに

Webアプリの作成で避けては通れないのがユーザー登録です。
更にそんなときについでにやりたくなるのがFacebookなどSNSを使ったユーザー登録ですよね。
何回もやっていて毎度調べるのが面倒だ~と思ったので、同じような境遇の方のための爆速で実装出来るまとめ記事です。

この記事で出来ること

  • Email/Passwordでのユーザー登録
  • Facebookでのユーザー登録
  • Twitterでのユーザー登録
  • Googleアカウントでのユーザー登録

対象読者

  • Railsにある程度慣れていて爆速でユーザー登録を実装したい方。

下準備

先に一通り必要なgemをインストールしておきます。Omniauthで必要が無いものがある場合は適宜省いてください。

Gemfile
gem 'devise'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'
bundle install --path vendor/bundle

Deviseでユーザー登録

a. Gemfileにdeviseを追加します。

gem 'devise'

b. 以下のコマンドを実行します。

bundle install --path vendor/bundle
bundle exec rails g devise:install # generator
bundle exec rails g devise:views # deviseのviewをコピー
bundle exec rails g devise User # モデルを作成
bundle exec rails db:migrate

c. ApplicationController.rbにauthenticate_user!を追記します。

ApplicationController.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user! # 追記 (userの部分はmodel名)
end

d. serverを起動し、/users/sign_upにアクセスして動作を確認します。
競馬AIたろう〜人工知能による競馬予想〜___競馬AIうまたろう〜人工知能による競馬予想〜_と_競馬AIたろう〜人工知能による競馬予想〜___競馬AIうまたろう〜人工知能による競馬予想〜.png

登録するとユーザーが作られていことが確認できます。

pry> User.first
  User Load (0.4ms)  SELECT  `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
#<User:0x007feed8b78ee0> {
                        :id => 1,
                     :email => "xxxxx@gmail.com",
...

これだけでユーザー登録の機能は完了です!

OmniAuth

続いてOmniAuthを実装していきます。

Railsの設定

Rails側の必要な変更をまとめて行います。

a. oauthに必要なカラムをuserテーブルに追加します。

bundle exec rails g migration AddOmniauthToUsers provider:string uid:string
bundle exec rake db:migrate

b. initializerにomniauth用の設定を追記します。scopeなど必要に応じて変更してください。

initializers/devise.rb
  config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: 'email', info_fields: 'email', callback_url: "#{ENV['HOST']}/users/auth/facebook/callback"
  config.omniauth :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_API_SECRET'], scope: 'email', oauth_callback: "#{ENV['HOST']}/users/auth/twitter/callback"
  config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], scope: 'email', redirect_uri: "#{ENV['HOST']}/users/auth/google_oauth2/callback"
  OmniAuth.config.logger = Rails.logger if Rails.env.development? # debug用

c. userモデルにomniauthableを追記。コールバックメソッドのfrom_omniauthを追加します。

user.rb
class User < ApplicationRecord
  devise :omniauthable, omniauth_providers: %i[facebook twitter google_oauth2]
  # omniauthのコールバック時に呼ばれるメソッド
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
    end
  end
end

d. config/routes.rbにrouteを追加します。

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

e. Users::OmniauthCallbacksControllerを作成します。

controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  # callback for facebook
  def facebook
    callback_for(:facebook)
  end

  # callback for twitter
  def twitter
    callback_for(:twitter)
  end

  # callback for google
  def google_oauth2
    callback_for(:google)
  end

  # common callback method
  def callback_for(provider)
    @user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
    else
      session["devise.#{provider}_data"] = request.env["omniauth.auth"].except("extra")
      redirect_to new_user_registration_url
    end
  end

  def failure
    redirect_to root_path
  end

end

f. /app/views/devise/registrations/new.html.erbに導線を追加します。以下のように書くことでdevise.rbで追加したoauthのリンクを表示してくれます。

app/views/devise/registrations/new.html.erb
<%= render "devise/shared/links" %>

競馬AIたろう〜人工知能による競馬予想〜___競馬AIうまたろう〜人工知能による競馬予想〜.png

各プラットフォーム毎の設定

続いて各プラットフォームごとの設定を行います。

Facebook

APPIDとSECRETはアプリ一覧ページから対象のアプリを選択し、Settings⇨Basicsから確認できます

keiba-ai-umataro_-_Settings_-_Facebook_for_Developers.png

また、FacebookLogin ⇨ Settings ⇨ Valid Oauth Redirect URLsにテスト用にコールバックさせるurlを追記しておきます。
ドメインは何か適当なものを使い(自分は簡単にローカルのサーバ−を公開できるngrokを使っています)

keiba-ai-umataro_-_Facebook_Login_-_Facebook_for_Developers.png
Valid OAuth Redirect URIsを

https://yourdomain/users/auth/facebook/callback

としておきます。

※ 本番で利用する際はプライバシーポリシーページを追加して & StatusをONにする必要があります。
keiba-ai-umataro.png

Twitter認証

a. twitter appにアクセスし、APIKEYとSECRETをコピー
umataro-bot___Twitter_Application_Management.png

b. callback urlを設定。privacy policy, terms of serviceも何か埋めておく
umataro-bot___Twitter_Application_Management.png

c. permissionはread only、ユーザー登録にメルアドが必要なので「Request email addresses from users」チェック

umataro-bot___Twitter_Application_Management.png

google

a. GCPのプロジェクトを作成しAPI認証の設定からOauthクライアントIDを作成します。
認証情報_-_mamorio.png

b. 作成出来たらクライアントIDとクライアントシークレットをメモしておき、リダイレクトURIを設定します

OAuth_クライアント_-_umataro.png

c. Google+のAPIを有効にしていないとエラーになるのでしていない場合は有効にしておきます。
API_とサービス_-_Umataro.png

追記: これと直接関係しませんが例えば、calendarのapiも合わせて認証したい場合に
scopeにcalendarのみを書くとエラーになります。
必ずemailをscopeに含める必要があるようです(参考)

  config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], scope: 'email,calendar', redirect_uri: "#{ENV['HOST_DOMAIN']}/users/auth/google_oauth2/callback"

確認

さてこれで全て完了です。
/users/sign_upにアクセスして
最後に動作の確認をして各oauthのリンクをクリックしてユーザー登録出来るか確認してみてください。
ユーザーが作成されてproviderとuidに値が入っていれば成功です。
(うまくいかない場合はrailsのlogを見てみると何がおかしいのかわかります)

最後に

いかがでしたでしょうか?
良くも悪くもRailsはなんでも簡単に出来てしまいますね。。。。
同じようにユーザー登録を実装したい方の役に立てれば幸いです。

kazuooooo
個人開発者やってます!
https://matsumotokazuya.io
admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。
https://admin-guild.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away