Facebook、vkontakteを使用したRailsアプリケーションでの認証

Facebook、vkontakteを介したRailsアプリケーションでの認証





この記事では、vkontakteおよびfacebookソーシャルネットワークを介してRailsアプリケーションで簡単な認証を行う方法を説明します; omniauth、omniauth-facebook、omniauth-vkontakte gemsはこれに役立ちます。 材料は初心者向けに設計されています。 これはトレーニングアプリケーションですが、ブートストラップを使用してtwitter-bootstrap-rails gemを完成させます。





フレーム



新しいアプリケーションを作成します(コマンドの前にbundle execを省略します)。

rails new authproviders
      
      





Gemfileに必要なgemを書き込みます

 source 'https://rubygems.org' gem 'rails', '3.2.3' gem 'sqlite3', :group => :development gem 'pg', :group => :production group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' gem 'uglifier', '>= 1.0.3' end gem 'jquery-rails' gem 'haml-rails' gem 'twitter-bootstrap-rails' gem 'devise' gem 'omniauth' gem 'omniauth-facebook' gem 'omniauth-vkontakte'
      
      





インストール:

 bundle install --without production
      
      





アプリケーションを少しきれいにして、ブートストラップを適用しましょう:

 rails g bootstrap:layout application fixed
      
      





パブリックディレクトリからindex.htmlを削除することを忘れないでください。

application.html.erbファイルが残っている場合は、それも削除します。

ユーザーモデルを作成します。ここで、urlはプロファイルページのアドレスです。

 rails g scaffold User username:string nickname:string provider:string url:string
      
      





deviseを構成します。

 rails generate devise:install rails generate devise User rake db:migrate
      
      





omn​​iauthableモジュールをユーザーモデルに追加します。

 class User < ActiveRecord::Base # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me attr_accessible :nickname, :provider, :url, :username end
      
      







各プロバイダーのアクションを含むコールバックコントローラーを作成する

 rails g controller Users::OmniauthCallbacks facebook vkontakte
      
      





Deviseからの継承:: OmniauthCallbacksController

 class Users::OmniauthCallbacksControllerController < Devise::OmniauthCallbacksController def facebook end def vkontakte end end
      
      





routes.rbにルーティングを書きます:

 Authproviders::Application.routes.draw do devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } resources :users, :only => [:index, :destroy] root :to => 'users#index' end
      
      







ソーシャルネットワークへのリンク(user_omniauth_authorize_path(:facebook)およびuser_omniauth_authorize_path(:vkontakte))をapplication.html.hamlテンプレート、完全なテンプレートコードに追加します。

 !!! 5 %html(lang="en") %head %meta(charset="utf-8") %meta(name="viewport" content="width=device-width, initial-scale=1.0") %title= content_for?(:title) ? yield(:title) : "Authproviders" = csrf_meta_tags / Le HTML5 shim, for IE6-8 support of HTML elements /[if lt IE 9] = javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js" = stylesheet_link_tag "application", :media => "all" %link(href="images/favicon.ico" rel="shortcut icon") %link(href="images/apple-touch-icon.png" rel="apple-touch-icon") %link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon" sizes="72x72") %link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon" sizes="114x114") %body .navbar.navbar-fixed-top .navbar-inner .container %a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse") %span.icon-bar %span.icon-bar %span.icon-bar %a.brand(href="#") Authproviders .container.nav-collapse %ul.nav - if user_signed_in? %li= link_to "#{current_user.username} (#{current_user.provider})", current_user.url %li= link_to "Sign out", destroy_user_session_path, :method => :delete .container .content .row .span9 = yield .span3 .well.sidebar-nav %h3 Providers %ul.nav.nav-list - if !user_signed_in? %li= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) %li= link_to "Sign in with Vkontakte", user_omniauth_authorize_path(:vkontakte) %footer %p © Company 2012 = javascript_include_tag "application"
      
      





users / index.html.hamlテンプレートを修正して、登録済みユーザーを表示しましょう

 - model_class = User.new.class %h1=t '.title', :default => model_class.model_name.human.pluralize %table.table.table-striped %thead %tr %th= model_class.human_attribute_name(:username) %th= model_class.human_attribute_name(:nickname) %th= model_class.human_attribute_name(:provider) %th= model_class.human_attribute_name(:sign_in_count) %th= model_class.human_attribute_name(:created_at) %th=t '.actions', :default => t("helpers.actions") %tbody - @users.each do |user| %tr %td= link_to user.username, user.url %td= user.nickname %td= user.provider %td= user.sign_in_count %td= user.created_at %td = link_to t('.destroy', :default => t("helpers.links.destroy")), user_path(user), :method => :delete, :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')), :class => 'btn btn-mini btn-danger'
      
      





すべてが機能していることを確認し、最も興味深いものに進みます。

 rails s
      
      







フェイスブック



https://developers.facebook.com/appsページにアクセスして、新しいアプリケーションを作成します



(サイトurlのlocalhostでデバッグするには、localhostを書くことができます:3000)

devise.rb初期化ファイルで、次の行を追加します。

 config.omniauth :facebook, 'APP_ID', 'APP_SECRET'
      
      





「APP_ID」、「APP_SECRET」は、新しいアプリケーションの作成時に発行された値に変更します。



Userモデルにfacebookメソッドを追加します。これは、ページのアドレスでユーザーを検索し、そうでない場合は新しいものを作成します(セキュリティの観点からは最適なソリューションではありませんが、これは単なる例です)。

 def self.find_for_facebook_oauth access_token if user = User.where(:url => access_token.info.urls.Facebook).first user else User.create!(:provider => access_token.provider, :url => access_token.info.urls.Facebook, :username => access_token.extra.raw_info.name, :nickname => access_token.extra.raw_info.username, :email => access_token.extra.raw_info.email, :password => Devise.friendly_token[0,20]) end end
      
      







Users :: OmniauthCallbacksControllerコントローラーで、facebookメソッドも追加します。

 def facebook @user = User.find_for_facebook_oauth request.env["omniauth.auth"] if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook" sign_in_and_redirect @user, :event => :authentication else flash[:notice] = "authentication error" redirect_to root_path end
      
      







ヴコンタクテ



連絡先の手順は似ています: http : //vk.com/developers.php

アプリケーションを作成します。



devise.rb初期化ファイルに行を追加することを忘れないでください:

 config.omniauth :vkontakte, 'APP_ID', 'APP_SECRET'
      
      





ローカルホスト上の連絡先での作業をテストすることはより困難であることが判明しました;このことを使用できます: https : //github.com/progrium/localtunnel

バンドルによるインストール後、最初の起動時にキーをロードします。

 localtunnel -k ~/.ssh/id_rsa.pub 3000
      
      





次に、トンネルを起動します。アプリケーションが使用可能になるアドレスを指定し(ハンマーで接触させます)、その後にレールが続きます。

 localtunnel 3000 This localtunnel service is brought to you by Twilio. Port 3000 is now publicly accessible from http://4v9p.localtunnel.com ... rails s
      
      





Facebookと同様に、モデルとコントローラーにvkontakteメソッドを追加します(連絡先情報セキュリティポリシーによると、メールアドレスは指定されていないため、検証と競合しないように、ユーザーを作成するときに、次の形式の代理アドレスを作成します:domain + @ vk.com) :

 class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable attr_accessible :email, :password, :password_confirmation, :remember_me attr_accessible :nickname, :provider, :url, :username def self.find_for_facebook_oauth access_token if user = User.where(:url => access_token.info.urls.Facebook).first user else User.create!(:provider => access_token.provider, :url => access_token.info.urls.Facebook, :username => access_token.extra.raw_info.name, :nickname => access_token.extra.raw_info.username, :email => access_token.extra.raw_info.email, :password => Devise.friendly_token[0,20]) end end def self.find_for_vkontakte_oauth access_token if user = User.where(:url => access_token.info.urls.Vkontakte).first user else User.create!(:provider => access_token.provider, :url => access_token.info.urls.Vkontakte, :username => access_token.info.name, :nickname => access_token.extra.raw_info.domain, :email => access_token.extra.raw_info.domain+'@vk.com', :password => Devise.friendly_token[0,20]) end end end
      
      





コントローラーコード:

 class Users::OmniauthCallbacksController < ApplicationController def facebook @user = User.find_for_facebook_oauth request.env["omniauth.auth"] if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook" sign_in_and_redirect @user, :event => :authentication else flash[:notice] = "authentication error" redirect_to root_path end end def vkontakte @user = User.find_for_vkontakte_oauth request.env["omniauth.auth"] if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Vkontakte" sign_in_and_redirect @user, :event => :authentication else flash[:notice] = "authentication error" redirect_to root_path end end end
      
      





もちろん、DRYを使用すると、このコードを一般化できますし、一般化する必要があります。

アプリケーション自体:








おわりに



これまで見てきたように、Facebookおよび連絡先を介した認証を使用してRailsでアプリケーションを作成するのは非常に簡単です。

動作するデモはこちら: http : //authproviders.herokuapp.com/

サンプルコード: https : //github.com/mystdeim/Authproviders

便利なリンクを次に示します。



PSこれは私の最初の記事、ペンのテストです、あなたは言うことができます。



UP: keiアプリケーションとidアプリケーションのキーを別々に保持して、誤ってリポジトリに落ちないようにする方が良いhttp://habrahabr.ru/post/142128/#comment_4757653



All Articles