認証機能 authenticated
アプリケーションを提供する立場にあるとき、無償の場合であってもユーザを限定して利用してもらうためには、何らかの仕組みが必要となります。それが認証機能です。今回はRuby on Rails上のアプリケーションに実装します。
1-1.プロジェクトの生成
(1) プロジェクトAppli004を生成する
(2) 日本語環境の設定
(3) データベースの作成
1-2.ログイン認証プラグインacts_as_authenticatedのインストール
(1) プラグインの導入
D:\Rails_Projects\Appli004>ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated
+ ./CHANGELOG
+ ./README
+ ./generators/authenticated/USAGE
+ ./generators/suthenticated/authenticated_generator.rb
+ ./generators/suthenticated/templates/authenticated_system.rb
+ ./generators/suthenticated/templates/authenticated_test_helper.rb
+ ./generators/suthenticated/templates/controller.rb
+ ./generators/suthenticated/templates/fixtures.yml
+ ./generators/suthenticated/templates/functional_test.rb
+ ./generators/suthenticated/templates/helper.rb
+ ./generators/suthenticated/templates/index.rhtml
+ ./generators/suthenticated/templates/login.rhtml
+ ./generators/suthenticated/templates/migration.rb
+ ./generators/suthenticated/templates/model.rb
+ ./generators/suthenticated/templates/signup.rhtml
+ ./generators/suthenticated/templates/unit_test.rb
+ ./generators/suthenticated_mailer/USAGE
+ ./generators/suthenticated_mailer/authenticated_mailer_generator.rb
+ ./generators/suthenticated_mailer/templates/activation.rhtml
+ ./generators/suthenticated_mailer/templates/notifier.rb
+ ./generators/suthenticated_mailer/templates/notifier_test.rb
+ ./generators/suthenticated_mailer/templates/observer.rb
+ ./generators/suthenticated_mailer/templates/signup_notification.rhtml
+ ./install.rb
acts_as_authenticated generator
====DEPRECATED: Use restful_authentication instead. Or, ask me for commit rights if
you wish to maintain this plugin.This is a basic authentication generator for rails, very much in the spirit of x
al's original Login Generator.To use:
./script/generate authenticated user account
This generates a basic user model, a controller, some basic views, and tests. E
xtra functionality can be unlocked by
removing the comments for them. I have a few examples such as user activation a
nd reversible encrypted passwords.This user migration is also generated unless you pass --skip-migration.
Generate your mailer:
./script/generate authenticated_mailer user
Consult the Acts As Authenticated wiki for more: http://technoweenie.stikipad.co
m/plugins/show/Acts+as+Authenticated
(2) authenticatedの生成
D:\Rails_Projects\Appli004>ruby script/generate authenticated user account
exists app/models/
exists app/controllers/
exists app/helpers/
exists app/views/account
exists test/functional/
exists test/unit/
create app/models/user.rb
create app/controllers/account_controller.rb
create lib/authenticated_system.rb
create lib/authenticated_test_helper.rb
create test/functional/account_controller_test.rb
create app/helpers/account_helper.rb
create test/unit/user_test.rb
create app/views/account/index.rhtml
create app/views/account/login.rhtml
create app/views/account/signup.rhtml
exists db/migrate
create db/migrate/20100204014203_create_users.rb
(3) NetBeansで[データベースマイグレーション]を選択し、[現在のバージョンへ]を実行します。
(in D:/Rails_Projects/Appli004)
== CreateUsers: migrating ====================================================
-- create_table("users", {:force=>true})
-> 0.1410s
== CreateUsers: migrated (0.1410s) ===========================================
(4) 動作確認
WEBrickを立ち上げます。
(5) signupの実行
ブラウザからhttp://127.0.0.1:3000/account/signupを起動します。signup画面が表示されます。
(6) テストデータの投入
数件登録してみましょう。
Login | Password |
---|---|
akagi | pwAkagi |
ito | pwIto |
ueno | pwUeno |
(7) loginの実行
次にブラウザからhttp://127.0.0.1:3000/account/loginを起動します。login画面が表示されます。
login動作を確認します。併せてhttp://127.0.0.1:3000/accunt/logoutの動きも確認してください。
1-3.ログイン認証プラグインの改良
通常のアプリケーションでは、上記のloginとlogoutを使いますが運用上loginに不足している機能があります。
それはパスワード変更機能です。ここではログイン時にパスワード変更機能を持たせるための改良を行います。
(1) ビューの修正
<% form_tag do -%>
<p><label for="login">Login</label><br/><%= text_field_tag 'login' %></p><p><label for="password">Password</label><br/><%= password_field_tag 'password' %></p>
<p><label for="new_password">New Password</label><br/><%= password_field_tag 'new_password' %></p><p><label for="new_password_confirmation">New Confirm Password</label><br/><%= password_field_tag 'new_password_confirmation' %></p>
<!-- Uncomment this if you want this functionality
<p><label for="remember_me">Remember me:</label><%= check_box_tag 'remember_me' %></p>
--><p><%= submit_tag 'Log in' %></p><% end -%>
(2) コントローラの修正
class AccountController < ApplicationController:
:
:
def login
return unless request.post?
return unless (params[:new_password] == params[:new_password_confirmation])
self.current_user = User.authenticate(params[:login], params[:password])
if logged_in?
if params[:remember_me] == "1"
self.current_user.remember_me
cookies[:auth_token] = { :value => self.current_user.remember_token ,
:expires => self.current_user.remember_token_expires_at }
end
flash[:notice] = "Logged in successfully"
if params[:new_password]
@user = User.find(self.current_user.id)
@user.password = params[:new_password]
@user.password_confirmation = params[:new_password_confirmation]
@user.save!
flash[:notice] = "Password changed"
end
redirect_back_or_default(:controller => '/board', :action => 'index')
end
rescue ActiveRecord::RecordInvalid
render :action => 'login'
end
:
:
:
end
(3) 動作確認
ブラウザからhttp://127.0.0.1:3000/account/loginを起動します。
1-4.アプリケーションの作成
(1) scaffoldの利用
NetBeansで[生成...]を選択
ジェネレータ(G): scaffold
モデル名(N): Address
属性ペア(フィールド型)(A): namae:string yubin:string jusho:string denwa:string
exists app/models/
exists app/controllers/
exists app/helpers/
create app/views/addresses
exists app/views/layouts/
exists test/functional/
exists test/unit/
create test/unit/helpers/
exists public/stylesheets/
create app/views/addresses/index.html.erb
create app/views/addresses/show.html.erb
create app/views/addresses/new.html.erb
create app/views/addresses/edit.html.erb
create app/views/layouts/addresses.html.erb
create public/stylesheets/scaffold.css
create app/controllers/addresses_controller.rb
create test/functional/addresses_controller_test.rb
create app/helpers/addresses_helper.rb
create test/unit/helpers/addresses_helper_test.rb
route map.resources :addresses
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/address.rb
create test/unit/address_test.rb
create test/fixtures/addresses.yml
exists db/migrate
create db/migrate/20100204020739_create_addresses.rb
(2) マイグレーションファイルの実行
NetBeansで[データベースマイグレーション]→[現在のバージョンへ]を選択します。
(in D:/Rails_Projects/Appli004)
== CreateAddresses: migrating ================================================
-- create_table(:addresses)
-> 0.0940s
== CreateAddresses: migrated (0.0940s) =======================================
(3) 生成されたプログラムの実行
http://127.0.0.1:3000/addresses/を実行します。
1-5.ログイン機能のアプリケーションへの組み込み
認証機能のaccountプログラムとアプリケーションであるaddressプログラムをそれぞれ独立して作成しましたが、ここでそのプログラムを合体します。ほとんどのアプリケーションはこの方法で十分です。
・addressesアプリケーションのすべてのメソッドを実行する前にLoginが済んでいるかチェックを入れる
・addressesアプリケーションの終了時にLogoutメソッドを呼び出す
・Loginメソッドの実行後、addressesアプリケーションのindexメソッド(最初のメソッド)を呼び出す
・Singupメソッドの終了後はLoginメソッドを呼び出す
・Logoutメソッドの終了後はLoginメソッドを呼び出す
(1) application_controller.rbの修正
account_controler.rbの上の方に書いてある以下のコーディングを入れます。
# 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
# Be sure to include AuthenticationSystem in Application Controller instead
include AuthenticatedSystem
# If you want "remember me" functionality, add this before_filter to Application Controller
before_filter :login_from_cookiebefore_filter :set_charset
private
def set_charset
headers['Content-Type']="text/html; charset=utf-8"
end
:
:
end
(2) account_controller.rbの修正
上の方に書いてある以下のコーディングを削ります。
class AccountController < ApplicationController
# Be sure to include AuthenticationSystem in Application Controller instead
include AuthenticatedSystem
# If you want "remember me" functionality, add this before_filter to Application Controller
before_filter :login_from_cookie# say something nice, you goof! something sweet.
def index
redirect_to(:action => 'signup') unless logged_in? || User.count > 0
end
:
:
end
(3) loginアクションの修正(戻り値の変更)
def login
return unless request.post?
self.current_user = User.authenticate(params[:login], params[:password])
if logged_in?
if params[:remember_me] == "1"
self.current_user.remember_me
cookies[:auth_token] = { :value => self.current_user.remember_token ,
:expires => self.current_user.remember_token_expires_at }
end
redirect_back_or_default(:controller => '/addresses', :action => 'index')
flash[:notice] = "Logged in successfully"
end
end
(4) signupアクションの修正(戻り値の変更)
def signup
@user = User.new(params[:user])
return unless request.post?
@user.save!
self.current_user = @user
redirect_back_or_default(:controller => '/account', :action => 'login')
flash[:notice] = "Thanks for signing up!"
rescue ActiveRecord::RecordInvalid
render :action => 'signup'
end
(5) logoutアクションの修正(戻り値の変更)
def logout
self.current_user.forget_me if logged_in?
cookies.delete :auth_token
reset_session
flash[:notice] = "You have been logged out."
redirect_back_or_default(:controller => '/account', :action => 'login')
end
(6) login事前チェックの導入
class AddressesController < ApplicationController
before_filter :login_required# GET /addresses
# GET /addresses.xml
def index
@addresses = Address.find(:all)respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @addresses }
end
end
:
:
end
(7) logoutへのリンク導入
<h1>Listing addresses</h1><table>
<tr>
<th>Namae</th>
<th>Yubin</th>
<th>Jusho</th>
<th>Denwa</th>
</tr><% for address in @addresses %>
<tr>
<td><%=h address.namae %></td>
<td><%=h address.yubin %></td>
<td><%=h address.jusho %></td>
<td><%=h address.denwa %></td><td><%= link_to 'Show', address %></td>
<td><%= link_to 'Edit', edit_address_path(address) %></td>
<td><%= link_to 'Destroy', address, :confirm => 'Are you sure?', :method => :delete %></td>
</tr><% end %>
</table>
<br /><%= link_to 'New address', new_address_path %>
<%= link_to 'Logout', {:controller => 'account', :action => 'logout'} %>