2009年9月6日日曜日

[Railsのキホン][プラグイン] restful_authentication の使いかた (1) 導入編

Rails 2.x での認証のデファクトらしい restful_authentication を触ってみます。
入門記事はたくさんあるのですが、、、知識不足でいまいちよくわからない --;; ので、ミニマルな機能から始めて少しずつ勉強していく予定。

環境
$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-linux]
$ rails -v
Rails 2.2.2


まずは、sandbox 用に新規アプリを作成。
$ rails auth_sampl
$ cd auth_sampl


restful_authentication プラグインのインストール。最新版を
git://github.com/technoweenie/restful-authentication.git
からとってきます。
$ script/plugin install git://github.com/technoweenie/restful-authentication.git
Initialized empty Git repository in .git/
....
$ ls vendor/plugins/
restful-authentication


次に、認証に必要なmodelとcontrollerを生成するgenerator を走らせます。README.textfile によると、
./script/generate authenticated user sessions \
—include-activation \
—stateful \
—rspec \
—skip-migration \
—skip-routes \
—old-passwords

と必須の引数の他に色々オプションがあります。
とりあえず、必須なのは最初の2つの引数なのでそれだけ指定してgenerate。
(最初の引数はmodel名, 2番目の引数はcontroller名を与えている。modelは単数形、controllerは複数形で与えることに注意。)

$ script/generate authenticated user sessions
...
create app/models/user.rb
create app/controllers/sessions_controller.rb
create app/controllers/users_controller.rb
...
create db/migrate/20090906070132_create_users.rb
route map.resource :session
route map.resources :users
route map.signup '/signup', :controller => 'users', :action => 'new'
route map.register '/register', :controller => 'users', :action => 'create'
route map.login '/login', :controller => 'sessions', :action => 'new'
route map.logout '/logout', :controller => 'sessions', :action => 'destroy'

と、いろいろ生成されます。

users_controller.rb で定義されているアクションは、new と create のみ。

# app/controllers/users_controller.rb
class UsersController < ApplicationController
include AuthenticatedSystem

# render new.rhtml
def new
@user = User.new
end

def create
logout_keeping_session!
@user = User.new(params[:user])
success = @user && @user.save
if success && @user.errors.empty?
self.current_user = @user # !! now logged in
redirect_back_or_default('/')
flash[:notice] = "Thanks for signing up! We're sending you an email with your activation code."
else
flash[:error] = "We couldn't set up that account, sorry. Please try again, or contact an admin (link is above)."
render :action => 'new'
end
end
end


sessions_controller.rb で定義されているアクションは、new, create, destroy。

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
include AuthenticatedSystem

# render new.rhtml
def new
end

def create
logout_keeping_session!
user = User.authenticate(params[:login], params[:password])
if user
self.current_user = user
new_cookie_flag = (params[:remember_me] == "1")
handle_remember_cookie! new_cookie_flag
redirect_back_or_default('/')
flash[:notice] = "Logged in successfully"
else
note_failed_signin
@login = params[:login]
@remember_me = params[:remember_me]
render :action => 'new'
end
end

def destroy
logout_killing_session!
flash[:notice] = "You have been logged out."
redirect_back_or_default('/')
end

protected
# Track failed login attempts
def note_failed_signin
flash[:error] = "Couldn't log you in as '#{params[:login]}'"
logger.warn "Failed login for '#{params[:login]}' from #{request.remote_ip} at #{Time.now.utc}"
end
end


routes.rb には、以下のルーティングが追加されています。

# config/routes.rb
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
map.login '/login', :controller => 'sessions', :action => 'new'
map.register '/register', :controller => 'users', :action => 'create'
map.signup '/signup', :controller => 'users', :action => 'new'
map.resources :users
map.resource :session


/logout にアクセスすると、sessions/destroy に、
/login にアクセスすると、sessions/new に、
/register にアクセスすると、users/create に、
/signup にアクセスすると、users/new に
とぶわけですね。

migration は users テーブルをcreateしています。

# db/migrate/yyyymmddxxxxx_create_users.rb
class CreateUsers < ActiveRecord::Migration
def self.up
create_table "users", :force => true do |t|
t.column :login, :string, :limit => 40
t.column :name, :string, :limit => 100, :default => '', :null => true
t.column :email, :string, :limit => 100
t.column :crypted_password, :string, :limit => 40
t.column :salt, :string, :limit => 40
t.column :created_at, :datetime
t.column :updated_at, :datetime
t.column :remember_token, :string, :limit => 40
t.column :remember_token_expires_at, :datetime


end
add_index :users, :login, :unique => true
end

def self.down
drop_table "users"
end
end


必要なモデル・コントローラがそろったら、db:migrate で usersテーブルを作ります。
$ rake db:migrate
(in /home/moco/workspace/ruby/rails/auth_sampl)
== CreateUsers: migrating ====================================================
-- create_table("users", {:force=>true})
-> 0.0957s
-- add_index(:users, :login, {:unique=>true})
-> 0.0659s
== CreateUsers: migrated (0.1626s) ===========================================


ここまでで、認証の仕組みはひとまずできています。
サーバを立ち上げて

/signup にアクセス。

ユーザ名、メールアドレス、パスワードを入力して Sign up をクリックするとデフォルトのWelcomeページに遷移します(Sign Up成功ページはない・・・)。
これでは登録されたのかどうかわからないので、usersテーブルを確認。
sqlite> select * from users;
1|cocomo||cocomo@cocomo.com|001f7df113033412887c112fe6e33cc145929b0c|992f7379d7e313a814595634743f1cc038cb966f|2009-09-06 07:48:29|2009-09-06 07:48:29||

登録成功。パスワードはしっかり暗号化されています。

/login にアクセス。
正しいユーザ名、パスワードを入力すると、デフォルトのWelcomeページへ。間違うと再度ログインページが表示されます。

/logout にアクセスすると、これまたWelcomeページへ。

users_controllerから判断するに、ユーザアカウント抹消の仕組みはない模様。

0 件のコメント:

コメントを投稿