こんにちは。田中(邦)です。

前回で開発環境の構築が完了したので、実際に開発していきましょう。

今回は

  • Twitter, FacebookのOAuth利用認証機能(OmniAuth利用)

について解説します。

Twitter, FacebookのOAuth利用認証機能

最近のウェブサービスの開発はソーシャルメディアを使ったログイン機能がつきものです。

TwtterやFacebookを利用したユーザ登録やログインの仕組みを作るのは通常OAuth2.0という仕様を満たしたコードを書かなければならないのですが、各ベンダーから提供されるライブラリや自前での実装を行うと結構めんどくさいです。

OmniAuthと呼ばれるgemを使うと簡単に実装できるので、今回はそれを使って実装していきましょう。

OmniAuthの導入

OmniAuthをインストールしましょう。コマンドひとつでインストールできます。


$ padrino g plugin omniauth

apply https://github.com/padrino/padrino-recipes/raw/master/plugins/omniauth_plugin.rb
 insert Gemfile
 insert app/app.rb
 create lib/omniauth_initializer.rb

これで必要なファイルが生成され、アプリケーションにイニシャライザが登録されたので必要な設定を記入していきます。

ですがその前にTwitterとFacebookでアプリの登録が必要です。

Twitter Developers  , Facebook Developers でそれぞれアプリを登録してください。

ドメインが決まっていなければlocalhostとか、Vagrantで利用しているIPで大丈夫です。

Twitter アプリ登録

アプリが登録できたら lib/omniauth_initializer.rb を編集しましょう。

consumer_key,consumer_secret, app_id, app_secret をそれぞれTwitterとFacebookから発行されたもので置き換えてください。

twitterとfacebook用のgemを別途インストールしないとダメみたいなのでGemfileに下記2行を追記し、bundle installを実行します。


gem 'omniauth-twitter'
gem 'omniauth-facebook'

ここまでできたらpadrino s -h 0.0.0.0でアプリを起動してみましょう。

Vagrantで起動している仮想マシンのIPが 192.168.50.4 とかであれば

http:// 192.168.50.4:3000/auth/twitter や http:// 192.168.50.4:3000/auth/facebook

にアクセスすると、それぞれTwitter、Facebookにリダイレクトされるはずです。

Modelとコールバック用URLの作成

TwitterやFacebookからリダイレクトされるコールバック用のURLとユーザの登録情報を保持するModelを作成しましょう。

まずModelの作成からです。


padrino g model user

これでModelが生成されました。

必要なフィールドを足していきます。生成されたModelにuidとproviderというフィールドを追加しましょう。

アクセス制御にはPadrino::Admin::AccessControlを使いたいのでroleも追加します。

ログイン用とユーザ登録用のメソッドも追加しておきます。

# for OmniAuth
field :uid, :type => String
field :provider, :type => String
# for Padrino::Admin::AccessControl
field :role, :type => String

#ユーザ登録用</span>
def self.create_with_omniauth(auth)
  create! do |user|
    user.provider = auth['provider']
    user.uid = auth['uid']
    user.role = "members"
  end
end

#ログイン用
def self.find_by_provider_and_uid(provider,uid)
  find_by(:uid => uid, :provider => provider) rescue nil
end

#Padrino::Admin::AccessControl用
def self.find_by_id(id)
  find(id) rescue nil
end

次にコールバック用のURLの作成です。

app/app.rb に次のようなControllerを追加します。ついでにアクセスコントロール周りの設定も追加です。


register Padrino::Admin::AccessControl
enable :authentication
enable :store_location

#Padrino::Admin::AccessControlはデフォルトでAccountモデルを認証に利用するのでUserに変更する

set :admin_model, 'User' # Default => Account

#デフォルトでは/home以下へのアクセスは禁止

access_control.roles_for :any do |role|
  role.protect "/home"
end

#membersというroleを持つユーザのみ/home以下へのアクセスを許可する。
access_control.roles_for :members do |role|
  role.allow "/home"
end

#コールバックを受けるためのControllerの作成
get :auth, :map => '/auth/:provider/callback' do
  auth = request.env["omniauth.auth"]
  #すでに登録されていればログイン、登録されていなければ登録してログインする。
  user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
  set_current_account(user)
  redirect url_for(:base,:home)
end

ログイン前のトップページとログイン後のトップページの作成

ユーザ登録とログイン機能はこれでできたので、画面を作ります。

下記コマンドを実行すると必要なファイルが生成されます。


padrino g controller base

生成されたapp/controller/base.rbを編集します。

get :index, :map => "/" do
  redirect url("/home") if current_account
  render "base/index"
end

get :home, :map => "/home" do
  "Provider: #{current_account.provider}, uid:#{current_account.uid} "
end

次にViewを作ります。

app/views/baseの中にindex.hamlを作成して次のように記述します。


Login with
=link_to('Facebook', '/auth/facebook')
or
=link_to('Twitter', '/auth/twitter')

これで / にアクセスするとログインメニューが表示され、twitterなりfacebookなりで認証が完了するとproviderとuidが表示されるはずです。

コードを書くのが面倒な方はこちらからどうぞ。

今回は以上になります。

お疲れ様でした。