# 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を入れていきます。
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ファイルが生成され中身を見ると以下のようになっていると思います。
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 を追加しましょう。
以下のようになって入ればオッケーです。
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での認証を実装していこうと思います。
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キーを取得しましょう。
右上にある「スタートガイド」ボタン(人によってはログインもしくはマイアプになっているかも)を押してログインを進める。 途中でメールアドレス(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)
gem 'dotenv-rails'
$ bundle install
次に「.env」というファイルをアプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)に作成します。
以下の図のようになっていればオッケーです。
次に作成した「.env」ファイルに以下を入力します。
FACEBOOK_ID='APP ID'
FACEBOOK_SECRET_KEY='APP Secret'
ここで'APP ID'と'APP Secret'は先ほどのFacebook Developersで取得したキーに書き換えておいてください(自分が取得したキーは絶対他言しないように!!)。
ので結果として以下のようになって入ればオッケーです。(数字は個々人によって変わります。)
FACEBOOK_ID='123456789012345' #←この数字は人によって違います!!
FACEBOOK_SECRET_KEY='1a2s3d4f5g6h7j8k9l0a1s2d4f5g6h1q' #←この数字は人によって違います!!
最後に隠しておきたいデータを定義した.envファイルをみんなに公開してしまっては意味が無いのでこのファイルは公開しないようにします。.gitignoreに下記を追加します。
# 省略
/.env
これでとりあえずOKです!
##7.APIキーの利用
config/initializers/devise.rbの259行目あたりに以下の記述がコメントアウトされていると思います
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
のでこの下の行に以下を追記してください。
# 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の組み合わせは一意であり、これによりユーザを取得する。
レコードに存在しない場合は作成する。
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 #ここはすでに記述されいてるのでコピペしなくていいです!
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を見ると以下のようになっていると思います。
Rails.application.routes.draw do
devise_for :users
# 省略(人によって違う。)
end
これを以下のように書き換えてOAuthのコールバック用のルーティングを設定してください。
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
# 省略(人によって違う。)
end
以上です!
rails sを実行して
localhost:3000/users/sign_up
に飛んで処理を確認してみてください!!