: O. Yuanying

Plugins - Open Id Authentication

前置き

OpenIDをRailsアプリで利用してみたかったので、Plugins - Open Id Authenticationという記事をかなりカタコトで訳してみました。

訳してみて気づいたこと。ソースを読めばわざわざ本文を訳す必要ないくらいわかりやすかったことorz

Plugins - Open Id Authentication

Open Id Authenticationプラグインは、JanRanによる、素晴らしいruby-openidライブラリの薄いラッパーをRailsに提供します。まず、最初にruby-openidをインストールしてください。

# gem install ruby-openid

OpenIDがどのようなもので、そしてどのように働くのかを理解するためには、lib/openid/consumer.rbのドキュメントが役に立つでしょう。

前提条件

OpenID認証はセッションを利用するので、セッションをオフにしていないか確認してください。また、RAILS_ROOTの下にtmp/openidsディレクトリがある必要があります。プラグインをインストールすることによって、install.rbはそれらを自動的にインストールしますが、もしあなたがinstall.rbを利用しなかった場合、あなた自身で確認する必要があります。

このプラグインは、認証動作(the authentication action)がPOSTとGET操作の両方を許可していることをあてにしています。もし、あなたがRESTfulな認証を利用しているのならば、あなたはroutes.rb中に明示的にこれらを許可する必要があります。

この例は、あなたがどのようにOpenID認証を利用することができるのかを説明するものです。あなたは、この上にプレーンテキストパスワードやその他の要件ではない、ハッシュ化されたログインを付け加えたいと思うでしょうが、この例は到着点ではなく、(OpenIDなどを利用した認証機構の)出発点として考えてください。

config/routes.rb

map.open_id_complete 'session', :controller => "session", :action => "create", :requirements => { :method => :get }
map.resource :session

app/controllers/session_controller.rb

  class SessionController < ApplicationController
    def create
      if open_id?(params[:name])
        open_id_authentication(params[:name])
      else
        password_authentication(params[:name], params[:password])
      end
    end

    protected
      def password_authentication(name, password)
        if @current_user = @account.users.find_by_name_and_password(params[:name], params[:password])
          successful_login
        else
          failed_login "Sorry, that username/password doesn't work"
        end
      end

      def open_id_authentication(identity_url)
        authenticate_with_open_id(identity_url) do |status, identity_url|
          case status
          when :missing
            failed_login "Sorry, the OpenID server couldn't be found"
          when :canceled
            failed_login "OpenID verification was canceled"
          when :failed
            failed_login "Sorry, the OpenID verification failed"
          when :successful
            if @current_user = @account.users.find_by_identity_url(identity_url)
              successful_login
            else
              failed_login "Sorry, no user by that identity URL exists"
            end
          end
        end
      end

    private
      def successful_login
        session[:user_id] = @current_user.id
        redirect_to(root_url)
      end

      def failed_login(message)
        flash[:error] = message
        redirect_to(new_session_url)
      end

      # Set #root_url if your root url has a different named route.
      #
      #   map.home '', :controller => ..., :action => ...
      #
      # Otherwise, name the route 'root' and leave this method out.
      def root_url
        home_url
      end
  end

簡単な登録用OpenID拡張

いくつかのOpenIdプロバイダは、軽量なプロファイル交換プロトコルをサポートしています。

あなたは先ほどの例のopen_id_authenticationメソッドを変更することで、これをサポートすることができます。

      def open_id_authentication(identity_url)
        # Pass optional :required and :optional keys to specify what sreg fields you want.
        # Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
        authenticate_with_open_id(identity_url, :required => [:nickname, :email], :optional => :fullname) do |status, identity_url, registration|
          case status
          when :missing
            failed_login "Sorry, the OpenID server couldn't be found"
          when :canceled
            failed_login "OpenID verification was canceled"
          when :failed
            failed_login "Sorry, the OpenID verification failed"
          when :successful
            if @current_user = @account.users.find_by_identity_url(identity_url)
              # registration is a hash containing the valid sreg keys given above
              # use this to map them to fields of your user model
              {'login=' => 'nickname', 'email=' => 'email', 'display_name=' => 'fullname'}.each do |attr, reg|
                current_user.send(attr, registration[reg]) unless registration[reg].blank?
              end
              unless current_user.save
                flash[:error] = "Error saving the fields from your OpenID profile: #{current_user.errors.full_messages.to_sentence}"
              end
              successful_login
            else
              failed_login "Sorry, no user by that identity URL exists"
            end
          end
        end
      end
Owner
David Heinemeier Hansson
Repository
http://svn.rubyonrails.org/rails/plugins/open_id_authentication/
License
Rails' (MIT)