Authlogic OpenID 1.0.3

Ruby ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]
Ruby on Rails 2.3.2
Authlogic 2.0.11
Authlogic OpenID 1.0.3

インストール

gem install authlogic
gem install authlogic-oid
gem install ruby-openid
ruby script/plugin install git://github.com/rails/open_id_authentication.git
rake open_id_authentication:db:create

config/environment.rb

config.gem "authlogic"
config.gem "authlogic-oid", :lib => "authlogic_openid"

セッションUserSessionの作成

ruby script/generate session user_session

app/models/user_session.rb

class UserSession < Authlogic::Session::Base
end

Userの作成

ruby script/generate model user persistence_token:string openid_identifier:string

app/models/user.rb

class User < ActiveRecord::Base
  validates_presence_of :openid_identifier
  acts_as_authentic

  private
  def attributes_to_save
#   attrs_to_save = attributes.clone.delete_if do |k, v|
#     [:password, crypted_password_field, password_salt_field, :persistence_token, :perishable_token, :single_access_token, :login_count,
#       :failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
#       :updated_at, :lock_version].include?(k.to_sym)
#   end
    attrs_to_save = attributes.clone.delete_if do |k, v|
      [:password, :persistence_token, :perishable_token, :single_access_token, :login_count,
        :failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
        :updated_at, :lock_version].include?(k.to_sym)
    end
#   attrs_to_save.merge!(:password => password, :password_confirmation => password_confirmation)
    attrs_to_save
  end
end

UserSessionsControllerの作成

ruby script/generate controller user_sessions new create destroy

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  helper :all
  protect_from_forgery
  helper_method :current_user_session, :current_user

  private
    def current_user_session
      return @current_user_session if defined?(@current_user_session)
      @current_user_session = UserSession.find
    end

    def current_user
      return @current_user if defined?(@current_user)
      @current_user = current_user_session && current_user_session.record
    end

    def require_user
      unless current_user
        store_location
        flash[:notice] = "You must be logged in to access this page"
        redirect_to new_user_session_url
        return false
      end
    end

    def require_no_user
      if current_user
        store_location
        flash[:notice] = "You must be logged out to access this page"
        redirect_to account_url
        return false
      end
    end

    def store_location
      session[:return_to] = request.request_uri
    end

    def redirect_back_or_default(default)
      redirect_to(session[:return_to] || default)
      session[:return_to] = nil
    end
end

app/controllers/user_sessions_controller.rb

class UserSessionsController < ApplicationController
  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => :destroy

  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    # Errorを防ぐ
    # [OPENID] Failed to fetch identity URL http://aaa/ : Error fetching http://aaa/: getaddrinfo: no address associated with hostname.
    if @user_session.openid_identifier &&
        !User.find_by_openid_identifier(@user_session.openid_identifier)
      @user_session.errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
      render :action => :new
    else
      @user_session.save do |result|
        if result
          flash[:notice] = "Login successful!"
          redirect_back_or_default account_url
        else
          render :action => :new
        end
      end
    end
  end

  def destroy
    current_user_session.destroy
    flash[:notice] = "Logout successful!"
    redirect_back_or_default new_user_session_url
  end
end

app/views/user_sessions/new.html.erb

<h1>Login</h1>
<% form_for @user_session, :url => user_session_path do |f| %>
  <%= f.error_messages %>
  <%= f.label :openid_identifier, "OpenID" %><br />
  <%= f.text_field :openid_identifier %><br />
  <br />
  <%= f.submit "Login" %>
<% end %>

config/routes.rb

map.resource :user_session, :only => [:new, :create, :destroy]
map.root :controller => "user_sessions", :action => "new"

UsersControllerの作成

ruby script/generate controller users new create show update destroy

app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => [:show, :destroy]

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    @user.save do |result|
      if result
        flash[:notice] = "Account registered!"
        redirect_back_or_default account_url
      else
        render :action => :new
      end
    end
  end

  def show
    @user = current_user
  end

  def destroy
    @user = @current_user
    @user.destroy
    flash[:notice] = "Account deleted!"
    redirect_to new_account_url
  end
end

app/views/users/_form.html.erb

<%= form.label :openid_identifier %><br />
<%= form.text_field :openid_identifier %><br />

app/views/users/new.html.erb

<h1>Register</h1>
<% form_for @user, :url => account_path do |f| %>
  <%= f.error_messages %>
  <%= render :partial => "form", :object => f %>
  <%= f.submit "Register" %>
<% end %>

app/views/users/show.html.erb

<p>
<b>OpenID:</b>
  <%=h @user.openid_identifier %>
</p>

config/routes.rb

map.resource :account, :controller => "users", :only => [:new, :create, :show, :destroy]