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
51
Help us understand the problem. What is going on with this article?
@makoto15

Railsで Facebook ログインを実装してみた

 Railsで作るFacebookログイン

こんにちは。今日はrailsで作るFacebookログイン機能を先日学んだのでメモ用としてここで記録していこうと思います。
では早速初めていきましょう。

全体を通して参考にしたサイト(https://freesworder.net/rails-facebook/)

0.前提

前提として、私はプログラミング習いたてで学習中の身であるので、稚拙なコードや文章等散見されるかもしれませんが、気になる点、誤った表現等あればご指摘いただけると幸いです。

1. アプリケーションを作る。

まずFacebookログインを実装するためのアプリケーションと基本的なコントローラを作成していきます。
今回のアプリケーション名は「facebook_login」とします。

ターミナル
$ rails new facebook_login
$ cd facebook_login
$ rails g controller hello index

2. Deviseの導入

次に gem を使ってdeviseを入れていきます。

gemfile
gem 'devise'
ターミナル
$ bundle install
$ rails generate devise:install
$ rails generate devise:controllers users
$ rails generate devise user
$ rails db:migrate

3.利用するモジュールの編集

deviseを導入すると app/models/user.rbファイルが生成され中身を見ると以下のようになっていると思います。

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

この devise: 以降に記述されている :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable はモジュールというものでどのモジュールを利用するかはここで定義することができます。
それぞれ何をするためのモジュールなのかは以下のリンクを参照してみることができます。
https://github.com/plataformatec/devise
また上記を日本語訳したリンクも貼っておきます(ただし少し古い記事になりますが...)
https://qiita.com/gakkie/items/6ef70c0788c3cbff81ee#i18n

ここに :omniauthable を追加しましょう。
以下のようになって入ればオッケーです。

app/models/user.rb
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

4.Omniauthでの認証

次にOmniauthでの認証を実装していこうと思います。

gemfile
gem 'omniauth'
gem 'omniauth-facebook'
ターミナル
$ bundle install

 カラムの追加

Omniauthではuid(一意のID)とprovider(FacebookやTwitterなど)をカラムとして利用します。
またnameカラムとimageカラムも追加してFacebookから名前とプロフィール画像を引っ張ってこられるようにします。

ターミナル
$ rails g migration AddColumnsToUsers uid:string provider:string name:string image:string
$ rails db:migrate

5. Facebook APIキーの取得

以下のリンクからAPIキーを取得しましょう。

Facebook Developers

スクリーンショット 2018-10-12 4.36.14.png
右上にある「スタートガイド」ボタン(人によってはログインもしくはマイアプになっているかも)を押してログインを進める。
途中でメールアドレス(Contact Email)とアプリ名(Display Name)を入力するところに行き着くと思いますが、アプリ名は正直適当でいいです(私は Makoto Shiraishi's first appにしました)。そこでCreateボタンを押しましょう。

作成が完了したら、設定より「Basic」→「Add Platform」(画面の一番下までスクロールしたら出てきます)→「Website」を選択する。
サイトURLにURLを入力する(例:http://localhost:3000/ )。
そして「変更を保存」ボタンを押してください。

ここから先の内容はちょっと筆者自身完璧に理解していないので、どういうコードを書くかについて言及を留めておきます。
わかり次第更新しいこうと思いますので、ご了承ください...

6.APIキーの非公開

先ほどFacebookのAPIを取得することができたと思いますが、この情報は非常に機密性が高く決して外部に漏らしてはいけない情報なので、このAPIキーが間違って公開されないような処理を施す必要があります。
のでこの節ではWebサービスを公開した時にAPIキーを公開しないようなコードを書いていくことにします。

参考にした記事(https://qiita.com/noraworld/items/bfa80811c9e30b4474af)

gemfile
gem 'dotenv-rails'
ターミナル
$ bundle install

次に「.env」というファイルをアプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)に作成します。
以下の図のようになっていればオッケーです。

スクリーンショット_2018-10-17_2_03_28.png

次に作成した「.env」ファイルに以下を入力します。

.env
FACEBOOK_ID='APP ID'
FACEBOOK_SECRET_KEY='APP Secret'

ここで'APP ID'と'APP Secret'は先ほどのFacebook Developersで取得したキーに書き換えておいてください(自分が取得したキーは絶対他言しないように!!)。
ので結果として以下のようになって入ればオッケーです。(数字は個々人によって変わります。)

.env
FACEBOOK_ID='123456789012345' #←この数字は人によって違います!!
FACEBOOK_SECRET_KEY='1a2s3d4f5g6h7j8k9l0a1s2d4f5g6h1q' #←この数字は人によって違います!!

 最後に隠しておきたいデータを定義した.envファイルをみんなに公開してしまっては意味が無いのでこのファイルは公開しないようにします。.gitignoreに下記を追加します。

.gitignore
# 省略

/.env

これでとりあえずOKです!

7.APIキーの利用

config/initializers/devise.rbの259行目あたりに以下の記述がコメントアウトされていると思います

config/initializers/devise.rb
 # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'

のでこの下の行に以下を追記してください。

config/initializers/devise.rb
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
config.omniauth :facebook, ENV['FACEBOOK_ID'], ENV['FACEBOOK_SECRET_KEY']  #←追加する部分はここ!

8. Userモデルにfindメソッドを実装とUserコントローラにコールバック処理を実装

以下を該当のファイルの好きな場所にコピペします。

uidとproviderの組み合わせは一意であり、これによりユーザを取得する。
レコードに存在しない場合は作成する。

app/models/user.rb
class User < ActiveRecord::Base #ここはすでに記述されいてるのでコピペしなくていいです!


  # 省略


  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:    auth.info.email,
        name:  auth.info.name,
        password: Devise.friendly_token[0, 20],
        image:  auth.info.image
      )
    end

    user
  end
end #ここはすでに記述されいてるのでコピペしなくていいです!
app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController #ここはすでに記述されいてるのでコピペしなくていいです!
  def facebook
    callback_from :facebook
  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を見ると以下のようになっていると思います。

config/routes.rb
Rails.application.routes.draw do
  devise_for :users

  # 省略(人によって違う。)

end

これを以下のように書き換えてOAuthのコールバック用のルーティングを設定してください。

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

  # 省略(人によって違う。)

end

以上です!

rails sを実行して

localhost:3000/users/sign_up
に飛んで処理を確認してみてください!!

51
Help us understand the problem. What is going on with this article?
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
makoto15
株式会社 WESEEK でエンジニアインターンとして在籍。 https://weseek.co.jp/。 大学生向けプログラミングコミュニティGeekSalonに元所属。 https://geek-salon.com/

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
51
Help us understand the problem. What is going on with this article?