Facebook認証を利用して、Ruby on Rails5 アプリケーションにログインできるようにしたい思います。
devise
+ OmniAuth
というGemを利用してFacebook認証を実装します。
【目 次】
Deviseとは
https://github.com/plataformatec/devise
Deviseは、Railsでログイン管理を簡単に行える便利なGemです。
新規登録時に認証メールを送信したり、ログイン・ログアウト機能も簡単に実装できます。
OmniAuthとは
OmniAuthは、簡単にWebアプリケーションのマルチプロバイダ認証を実装することができるGemです。
FacebookやTwitter等のSNS認証を実装する際に利用すると便利です。
それぞれに、Gemが公開されているので、今回は、Facebook用のGemをインストールをして実装していきたいと思います。
環境
Ruby on Rails 5.0.1
Facebookアプリケーションの作成
Facebook Developers でアプリケーションを作成します。
「製品を追加」を選択して、「Facebookログイン」の「スタート」ボタンをクリックします。
ひとまず、設定する箇所は「有効なOAuthリダイレクトURL」です。
認証するアプリケーションのURLを設定します。
「変更を保存」をクリックします。
Deviseのインストール
次に、Deviseのインストールと設定を行っていきます。
Gemfileに下記を追加します。
gem 'devise'
bundleインストールを行ないます。
$ bundle install --path vendor/bundle --jobs=4
deviseのファイルを生成します。
$ bundle exec rails g devise:install
Running via Spring preloader in process 39790
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
===============================================================================
こんな出力がされればOKです。
Deviseで出力されるメッセージを日本語化します。
英語版のymlファイルを、日本語版としてコピーします。
$ cp -p config/locales/devise.en.yml config/locales/devise.ja.yml
中のメッセージを日本語に置き換えます。
Userモデルを生成します。
$ bundle exec rails g devise user
Running via Spring preloader in process 13886
invoke active_record
create db/migrate/20170304210629_devise_create_users.rb
create app/models/user.rb
invoke rspec
create spec/models/user_spec.rb
invoke factory_girl
create spec/factories/users.rb
insert app/models/user.rb
route devise_for :users
マイグレーションの実行
$ bundle exec rake db:migrate
ログイン画面を表示します。
http://localhost:3000/users/sign_up
メールでのログイン認証画面が表示されればOKです。
認証機能の実装
Gemfileに追記します。
gem 'omniauth'
gem 'omniauth-facebook'
インストールします。
$ bundle install --path vendor/bundle --jobs=4
Userモデルに、カラムを追加します。
app/models/user.rb
bundle exec rails g migration AddColumnsToUsers uid:string provider:string
マイグレーションの実行
$ bundle exec rake db:migrate
Deviseの設定
Facebookアプリケーションの アプリID
と app secret
を追記します。
config/initializers/devise.rb
Devise.setup do |config|
## 省略
config.omniauth :facebook, ENV['APP_ID'], ENV['APP_SECRET']
end
Gitでソース管理したいので、直接 アプリID
と app secret
を記載することは避けて、環境変数から呼び出せるようにします。
.evnに環境変数を設定
DotenvというGemを利用して環境変数を読み込んでいるのですが、導入手順はこちらで紹介しています。
RailsにDotenvを導入!環境変数を管理しよう!
Facebookアプリケーションの「設定->ベーシック」に記載されている、 アプリID
と app secret
を、 .env
に設定します。
APP_ID="xxxxxxxxxxxxxxxx"
APP_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxx"
:omniauthable
を追記します。
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
end
Userモデルにメソッドを追加します。
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
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
コールバック処理を実装
ディレクトリを作成します。
mkdir app/controllers/users
コールバックの処理を実装します。
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
Rails.application.routes.draw do
# コールバック用URL
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
# ログアウト用
devise_scope :user do
delete :sign_out, to: 'devise/sessions#destroy', as: :destroy_user_session
end
end
ログイン画面を表示
http://localhost:3000/users/sign_up
「Sign in with Facebook」というリンクが表示されていたらOKです。
他のviewに記載したい場合は、下記をviewに記述します。
user_omniauth_authorize_path(:facebook)
URLを読み込めません:このURLのドメインはアプリノドメインに含まれていません。
このURLを読み込むには、アプリ設定のアプリドメインにすべてのドメインとサブドメインを追記してください。
リンクをクリックして、このようなメッセージが表示されたらFacebookアプリケーションの設定「有効なOAuthリダイレクトURI」が設定できているか見直してみてください。
「http://localhost:3000」を追加しておくとローカルでも認証が行えます。
最後に、私はヘッダーに、ログイン/ログアウトのURLを実装しました。
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Bgclub</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<div>
<% if user_signed_in? %>
<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'Sign in', user_facebook_omniauth_authorize_path %>
<% end %>
</div>
<%= yield %>
</body>
</html>
以上で、Facebook認証の実装は完了とします。
今回は、Devise+OmniAuthでユーザ認証を実装する手順を参考にさせていただきました。
ありがとうございました!
Ruby on Rails が学べるオンライン講座
オンライン講座なら、好きな場所で好きな時間に学習できます。Ruby on Rails も学ぶことができるので、ぜひ、活用しましょう。
Udemy(ユーデミー)
オンライン動画学習サイトで、Ruby on Rails講座やRuby講座もあります。頻繁に講座のバーゲンセールスが実施されているので、価格をチェックしましょう!一度、購入した動画は繰り返し使えますので何度でも学習可!
世界最大級のオンライン学習サイトUdemy
CodeCamp(コードキャンプ)
現役のRubyエンジニアによる個別指導で、Webサイト制作を基礎から習得できます。無料体験レッスンが受講できるので、気軽に受講体験ができます。
Ruby と Ruby on Railsマスターコース