ホーム > RoR > RailsアプリにOpenIDによる認証を実装する

RailsアプリにOpenIDによる認証を実装する

RailsアプリケーションにOpenIDによる認証システムを実装してみる
Ruby 1.8.7, Rails 2.0.2, Mac OSX Leopard
参考記事:OpenIDとRails:Authentication 2.0


MySQLでデータベースの作成(openidという名前で)

mysql> create database openid_development;

データベースに権限を設定

mysql> grant all on openid_development.* to 'root'@'localhost' identified by '';
(user名はrootでpasswordなし)

Railsアプリケーションの作成

$ rails -d mysql openid
※openidという名前で

scaffoldジェネレータを実行。このときにテーブルで使用するフィールドも定義。
※モデル名はTodo

$ ruby script/generate scaffold Todo person:string email:string start:date end:date description:text

マイグレーションを実行してテーブルを作成。

$ rake db:migrate

openidライブラリのインストール

$ sudo gem install ruby-openid

openid_authenticationプラグインをインストール

$ ruby script/plugin install open_id_authentication

Railsと、インストールしたruby-openidライブラリを統合する。
rakeコマンドを実行して必要なテーブルを作成し直す。
※open_id_authenticationプラグインをインストールしたことで open_id_authentication が使用できるようになる。
※このrakeタスクを実行するとruby-openidライブラリが使用するデータを保存するためのデータベースが生成される。
※生成されるテーブルは open_id_authentication_associations(OPと共有する共通鍵を保存する)と open_id_authentication_nonces(認証ごとに使用するnonceを保存する)の二つ。

$ rake open_id_authentication:db:create
$ rake db:migrate

アプリケーションコードの修正
app/controllers/application.rb を開いて次の authorize メソッドを追加。
※def authorize 部分から最後まで。

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time

  # See ActionController::RequestForgeryProtection for details
  # Uncomment the :secret if you're not using the cookie session store
  protect_from_forgery # :secret => '4c90f36b19f28833d59c3c3986f13673'
end

def authorize
  unless session[:user_id]
    flash[:notice] = "Please log in"
    # save the URL the user requested so we can hop back to it
    # after login
    session[:jumpto] = request.parameters
    redirect_to(:controller => "/login", :action => "index")
  end
end

このメソッドは有効な視覚情報がないと実行出来ない処理をユーザが要求した際にその要求を中断してログイン画面にリダイレクトする。また、このメソッドは要求パラメータをセッションの :jumpto シンボルに格納してログイン画面を生成する。ユーザはログインするとすぐに最初に要求したURLに転送される。

次に、app/controllers/todos_controller.rb を開いて次のように before_filter を追記する。
※before_filter :authorize, から最後まで。

class TodosController < ApplicationController
  before_filter :authorize,
    :o nly => [ :new , :edit, :create, :update, :destroy]

ログインコントローラーによる認証の仕組みを実装する

$ script/generate controller login

app/controllers/login_controller.rb というファイルが生成されるので、これを以下の内容に編集する。

require 'ostruct'

class LoginController < ApplicationController

  def index
    redirect_to :controller => "todos" if session[:user_id]
  end

  def login
    if using_open_id?
      authenticate
    else
      flash[:error] = "You must provide an OpenID URL"
      redirect_to :action => "index"
    end
  end

  def logout
    session[:user_id] = nil
    redirect_to :action => "index"
  end

  protected
    def authenticate(identity_url = "")
      authenticate_with_open_id(
      params[:openid_url], :required => [:nickname, :email]) do
        |result, identity_url, registration|

        if result.successful?
          @user = OpenStruct.new
          @user.identity_url = identity_url
          @user.nickname = registration["nickname"]
          @user.email = registration["email"]
          session[:user_id] = @user

          jumpto = session[:jumpto] || { :controller => "todos" }
          session[:jumpto] = nil
          redirect_to(jumpto)
        else
          flash[:error] = result.message
          redirect_to :action => "index"
        end
      end
    end

    def root_url
      openid_url
    end
end

ログインページを作成
※この時点ではまだログインするためのページ(view)がないので、次のコードを記述して
app/views/login/index.html.erb
というファイルを作成する。

<% if flash[:error] -%>
<%= flash[:error] %>
<% end -%>

<% form_tag :controller => "login" , :action => "login" do |f| -%>
  <label for="openid_url" >
    OpenId URL:
  </label>
  <%= text_field_tag :o  penid_url -%>
  <%= submit_tag "Login" -%>
<% end -%>

routes.rbに適切な経路を定義する
以下の内容を追記する。
※map.openid “login”, から最後まで。

ActionController::Routing::Routes.draw do |map|
  map.resources :todos

  map.openid "login",
    :controller => "login" ,
    :requirements => { :method => :get }

    def root_url
      openid_url
    end

コメント:6

free 2011年1月24日

はじめまして。
こちら、学生でOpenIDの実装をしてみようと考えいるものなのですが、

routes.rbに内容を追記した後、何を行えばアプリケーションが動作しているかどうかを確認できるのでしょうか?

admin 2011年1月26日

> 学生さん
ごめんなさい。これ、実際にやったのはもっとずっと前で
正直、いま全然おぼえてないんですよ(>_<)

なので、どうこたえていいやら。お恥ずかしい話ですが。

時間、機会作ってもっかいなぞればいいのかもしれませんが
ここしばらくはその時間なさそうで。

お役に立てずすいません。

admin 2011年1月26日

> 学生さん
自分が参照したCodeZineの記事、もう公開してないんですね。
あれがあればきっとわかったと思うのですが。面目ないです。

free 2011年1月27日

わかりました。

返信ありがとうございます!

free 2011年1月27日

CodeZineの記事とは
http://japan.internet.com/developer/20080627/26.html
のことでしょうか?

admin 2011年1月27日

> 学生さん
そうかもしれません。自分はこのエントリの冒頭で
示したhttp://codezine.jp/article/detail/2514?p=1を
見ながらやってみたのですが、このURLだともう
該当記事が読めなくて。タイトルが同じなので、この記事URLだと
思いますよ。自分、全然詳しくないですが、とりあえず出来た
おぼえがあるので、トライしてみてください!

コメントフォーム
入力した情報を記憶する

トラックバック:0

この記事のトラックバック URL
http://showzine.info/blog/2009/01/rails%e3%82%a2%e3%83%97%e3%83%aa%e3%81%abopenid%e3%81%ab%e3%82%88%e3%82%8b%e8%aa%8d%e8%a8%bc%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%99%e3%82%8b.html/trackback
トラックバックの送信元リスト
RailsアプリにOpenIDによる認証を実装する - SHOWJIN*BLOG より

ホーム > RoR > RailsアプリにOpenIDによる認証を実装する

検索
フィード

ページの上部に戻る