概要
新しいサービスを利用するのにユーザ登録が必要な場合、利用者にとっては手間がかかり利用するハードルが上がってしまいます。
しかし、現在広く使われている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を紐付けて様々なウェブサービスの開発ができることに期待します。