概要
新しいサービスを利用するのにユーザ登録が必要な場合、利用者にとっては手間がかかり利用するハードルが上がってしまいます。
しかし、現在広く使われているTwitterやFacebookアカウントを利用した認証機能を使うことで、ユーザは気軽にアプリケーションを利用できるはずです。
本記事ではRailsアプリケーションでOmniAuthを用いてTwitterとFacebookアカウントの認証をする方法を記します。
環境
1.TwitterAPI,FacebookAPIにアプリケーションを登録する
以下のURLからそれぞれアプリケーション登録を行い、アプリケーションID(APIキー)とSecretキー(APIシークレット)をメモしておきます。
それぞれの詳しい登録方法は以下のサイトを参考にしてください
※FacebookAPIでは、基本データから、「+Add Platform」で「ウェブサイト」を選択し、「サイトURL」の入力を忘れないで下さい。
2. アプリケーションの作成
2.1 OmniAuthのインストール
- プロジェクトを作成したらGemfileに必要なgemを追加します
- 本環境では、'omniauth-facebook'のバージョン1.4.1以上では動作を確認できませんでしたので1.4.0を利用しています
$ vim Gemfile -- # 以下を追記 gem 'omniauth-twitter' gem 'omniauth-facebook', '1.4.0'
- bundle installを実行
$ bundle install
2.2 モデルの作成
- 認証したユーザ情報を保存する為のモデルを作成
- 以下のコマンドを実行しUserという名のモデルを作成します
$ rails g model User provider uid name image oauth_token oauth_expires_at:datetime
- db:migrateを実行します
$ rake db:migrate
- Userモデルのレコード作成をOmniAuthのデータを用いて行う関数を用意
$ vim app/models/user.rb
--
class User < ActiveRecord::Base
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
unless auth.info.blank?
user.name = auth.info.name
user.screen_name = auth.info.screen_name
user.image = auth.info.image
end
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at) unless auth.credentials.expires_at.nil?
user.save!
end
end
end
2.3 セッション管理設定
- ApplicationControllerにアプリケーション内で共通に利用出来るヘルパーメソッドと呼ばれる関数を作成
- ここでは現在のユーザ情報を取得するcurrent_user関数を作成
$ vim app/controllers/application_controller.rb
--
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
- セッション管理のためのコントローラ"sessions"を作成
- 内部ではOmniAuthのサインイン情報から、登録されているユーザかどうかの検索を行う
- サインイン中はsession[:user_id]にユーザIDが保存される
- サインアウト時にはsession[:user_id]を削除
$ rails g controller sessions
$ vim app/controllers/session_controller.rb
--
# coding: utf-8
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_path, :notice => 'サインインしました'
end
def destroy
session[:user_id] = nil
redirect_to root_path, :notice => ' サインアウトしました'
end
def oauth_failure
redirect_to root_path, :notice => ' サインイン処理が中断されました'
end
end
2.4 OmniAuthの設定
- /config/initializer/omniauth.rbを新規作成します
- ここでtwitterやFacebookのIDとシークレットキーを入力します
- APPIDやAPP_SECRETは先程メモしておいたキーを入力します
$ vim config/initializer/omniauth.rb -- OmniAuth.config.logger = Rails.logger OmniAuth.config.on_failure = SessionsController.action(:oauth_failure) Rails.application.config.middleware.use OmniAuth::Builder do provider :facebook, 'APPID', 'APP_SECRET' provider :twitter, 'Consumer Key’,’Consumer Secret’ end
2.5 ルーティング設定
- 認証を可能にするために以下のルーティングを追加します
$ vim config/routes.rb
--
match 'auth/:provider/callback', to: 'sessions#create', via: [:get, :post]
match 'auth/failure', to: redirect('/'), via: [:get, :post]
match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post]
2.6 サインインリンクとユーザ情報の表示
- すべての画面でサインイン状態を示すためapplication.html.erbを編集
- 2.4で作成したヘルパーメソッドでcurrent_userが取得できる
- サインインしていない場合はサインインリンクを表示
$ vim app/view/layout/application.html.erb
--
<body>
<div id="user-widget">
<% if current_user %>
ようこそ<%= current_user.name %>
<%= link_to "Sign out", signout_path, id: "sign_out" %>
<% else %>
<%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %>
<%= link_to "Sign in with Twitter", "/auth/twitter", id: "sign_in" %>
<% end %>
</div>
<%= yield %>
</body>
</html>
注意
- 2.6のコード内の
/auth/twitterのようにリンク先が設定されている箇所について
おわりに
以上のステップでRails4でサインインとサインアウトの処理が可能になったと思います。 この先はcurrent_userのIDやセッション情報と各種データ、APIを紐付けて様々なウェブサービスの開発ができることに期待します。