2011年11月6日日曜日

OpenIDプラグインを使ってみる RP構築編

RubyのOpenIDプラグインを使用し、RPを構築する。


①OpenIDのプラグインをgemコマンドを使用してインストールする。
c:\ruby-openid\examples\rails_openid>gem install ruby-openid
c:\ruby-openid\examples\rails_openid>gem install openid_login_generator

②railsコマンドを使用し、railsアプリを作成する。DBはsqlite3を使用する。

c:\>rails -d sqlite3 openid_app
      create
      create  app/controllers
      create  app/helpers
      create  app/models
      create  app/views/layouts
      create  config/environments
      create  config/initializers
      create  config/locales
      create  db
      create  doc
      create  lib
      create  lib/tasks
      create  log
      create  public/images
      create  public/javascripts
      create  public/stylesheets
      create  script/performance
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/performance
      create  test/unit
      create  vendor
      create  vendor/plugins
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  Rakefile
      create  README
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  config/database.yml
      create  config/routes.rb
      create  config/locales/en.yml
      create  db/seeds.rb
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/new_rails_defaults.rb
      create  config/initializers/session_store.rb
      create  config/initializers/cookie_verification_secre
      create  config/environment.rb
      create  config/boot.rb
      create  config/environments/production.rb
      create  config/environments/development.rb
      create  config/environments/test.rb
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/runner
      create  script/server
      create  script/plugin
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  test/test_helper.rb
      create  test/performance/browsing_test.rb
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/index.html
      create  public/favicon.ico
      create  public/robots.txt
      create  public/images/rails.png
      create  public/javascripts/prototype.js
      create  public/javascripts/effects.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/controls.js
      create  public/javascripts/application.js
      create  doc/README_FOR_APP
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
c:\>



③generateコマンドを使用し、OpenID RPの雛形を作成する。

c:\>cd openid_app
c:\openid_app>ruby script\generate openid_login consumer
      create  lib/openid_login_system.rb
      create  app/controllers/consumer_controller.rb
      create  test/functional/consumer_controller_test.rb
      create  app/helpers/consumer_helper.rb
      create  app/models/user.rb
      create  test/unit/user_test.rb
      create  test/fixtures/users.yml
      create  app/views/layouts/scaffold.rhtml
      create  public/stylesheets/scaffold.css
      create  app/views/consumer
      create  app/views/consumer/welcome.rhtml
      create  app/views/consumer/login.rhtml
      create  app/views/consumer/logout.rhtml
      create  README_LOGIN



ジェネレータを使ってマイグレーションファイルを用意する。 このとき、OpenID ログインジェネレータが生成した user.rb を上書きしないように注意する。

  • プラグインのインストール
    C:\Ruby187\lib\ruby\gems\1.8\gems\ruby-openid-2.1.8\examples にあるactive_record_openid_store をrailsのプロジェクトのvendor/pluginにコピーする。
  • migrateファイルのコピー
    active_record_openid_storeフォルダに入っているXXX_add_open_id_store_to_db.rbを、db/migrateにコピーする。XXXを適当なナンバーに変更する。


c:\openid_app>ruby script\generate model user openid_url:string
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
overwrite app/models/user.rb? (enter "h" for help) [Ynaqdh] n
        skip  app/models/user.rb
overwrite test/unit/user_test.rb? (enter "h" for help) [Ynaqdh] n
        skip  test/unit/user_test.rb
overwrite test/fixtures/users.yml? (enter "h" for help) [Ynaqdh] n
        skip  test/fixtures/users.yml
      create  db/migrate
      create  db/migrate/20111105162817_create_users.rb



rake コマンドで users テーブルを作成する。 ユーザテーブルのカラムは id と openid_url の2つ。

c:\openid_app>rake db:migrate
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0080s
==  CreateUsers: migrated (0.0090s) ===========================================
==  AddOpenIdStoreToDb: migrating =============================================
-- create_table("open_id_associations", {:force=>true})
   -> 0.0250s
-- create_table("open_id_nonces", {:force=>true})
   -> 0.0020s
==  AddOpenIdStoreToDb: migrated (0.0280s) ====================================


⑥rails バージョン2で動作するように、ソースを修正する。

■ConsumerController.rb
◎@params、@requestや@sessionの@をはずす。
◎completeメソッドの全面的な書き換え。
OpenID::SUCCESS→OpenID::Consumer::SUCCESSへ修正。
OpenID::Filesystem.new→OpenID::Store::Filesystem.newへ修正。


require "pathname"
require "cgi"
require "openid"
require 'openid/extensions/sreg'
require 'openid/extensions/pape'
require 'openid/store/filesystem'


class ConsumerController < ApplicationController
  layout  'scaffold'
  
  # process the login request, disover the openid server, and
  # then redirect.
  def login
openid_url = params[:openid_url]
if request.post?
begin
request = consumer.begin(openid_url)
return_to = url_for(:action=>'complete')
trust_root = url_for(:controller=>"")
url = request.redirect_url(trust_root, return_to)
redirect_to(url)
rescue OpenID::OpenIDError
flash[:notice] = "Authorization failed."
end
end
  end


  # handle the openid server response
  def complete
    current_url = url_for(:action => 'complete', :only_path => false)
    parameters = params.reject{|k,v|request.path_parameters[k]}
    response = consumer.complete(parameters, current_url)
    
    case response.status
    when OpenID::Consumer::SUCCESS


      @user = User.get(response.identity_url)
      
      # create user object if one does not exist
      if @user.nil?
        @user = User.new(:openid_url => response.identity_url)
        @user.save
      end


      # storing both the openid_url and user id in the session for for quick
      # access to both bits of information.  Change as needed.
      session[:user_id] = @user.id


      flash[:notice] = "Logged in as #{CGI::escape(response.identity_url)}"
       
      redirect_to :action => "welcome"
      return


    when OpenID::FAILURE
      if response.identity_url
        flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."


      else
        flash[:notice] = 'Verification failed.'
      end
    when OpenID::CANCEL
      flash[:notice] = 'Verification cancelled.'
    else
      flash[:notice] = 'Unknown response from OpenID server.'
    end
  
    redirect_to :action => 'login'
  end
  
  def logout
    session[:user_id] = nil
  end
    
  def welcome
  end


  private
  # Get the OpenID::Consumer object.
  def consumer
    # create the OpenID store for storing associations and nonces,
    # putting it in your app's db directory
    store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
    store = OpenID::Store::Filesystem.new(store_dir)
    return OpenID::Consumer.new(session, store)
  end
  # get the logged in user object
  def find_user
    return nil if session[:user_id].nil?
    User.find(session[:user_id])
  end
end

■user.rb
 find_first→find_by_openid_urlへ修正。
# this model expects a certain database layout and its based on the name/login pattern. 
class User < ActiveRecord::Base
  def self.get(openid_url)
    find_by_openid_url(["openid_url = ?", openid_url])
  end  
  protected
  validates_uniqueness_of :openid_url, :on => :create
  validates_presence_of :openid_url
end

■login.rhtml
◎<%= start_form_tag :action=> "login" %>→<% form_tag  :action=> "login" do %>へ修正。
<% form_tag  :action=> "login" do %>
<div title="Account login" id="loginform" class="form">
    <h3>Please login</h3>
    <label for="user_login">Login:</label><br/>
    <input type="text" name="openid_url" id="openid_url" size="30" value=""/><br/>
    <br/>
    <input type="submit" name="login" value="Login &#187;" class="primary" />
</div>
<% end %>


⑦サーバを起動する。

c:\openid_app>ruby script\server
=> Booting Mongrel
=> Rails 2.3.8 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server

⑧「http://localhost:3000/consumer/login」にアクセスし、ログイン画面が表示されることを確認する。



0 件のコメント: