こんにちは。田中(邦)です。
前回で開発環境の構築が完了したので、実際に開発していきましょう。
今回は
- 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で大丈夫です。
アプリが登録できたら 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が表示されるはずです。
コードを書くのが面倒な方はこちらからどうぞ。
今回は以上になります。
お疲れ様でした。