目次

2009年1月26日月曜日

Ruby on Rails チュートリアル(3) ~pluginを使わずにログイン機能を作ってみよう~

ちょこっとやってみたらものの数分でログイン/セッション機能が完成して、とても嬉しくなりました。プラグインのおかげです。railsって本当に素晴らしい。

が、これではいつまでたってもRailsでのログイン設計を理解できるようになりません。悩みましたが、プラグインを使わずにログイン機能を作るチュートリアルにします!長くなりますが、頑張りましょう!!!このブログの順番がごちゃごちゃですがtest003(チュートリアル(4))を使います。失敗する恐れもありますので、同じ手順でtest004を今回新たに作り直しました。


ログインしないと、ユーザーデータが見れないようにします。

ログイン機能を作るための手順です。
(1) テーブルにフィールドを追加する(ログイン名とパスワード)
(2) user.rb modelの編集
(3) ymlの編集
(4) login controllerとview(ログインのindexページ)を作る
(5) application.rbの編集
(6) users_controllerの編集

さあ張り切って行きましょう。

(1) テーブルにフィールドを追加する(ログイン名とパスワード)
ログイン名とパスワード追加用のマイグレーションファイルを作ります。
$ ruby script/generate migration alter_users
中身はこんな感じです。パスワードは暗号化します。

db>migrate>XXXXXXXX_alter_users.rb
class AlterUsers < ActiveRecord::Migration

def self.up
add_column :users, :login_name, :string, # ログイン名
:null => false
add_column :users, :hashed_password, :string
# 暗号化されたパスワード
add_column :users, :salt, :string # パスワードソルト
end

def self.down
remove_column :users, :login_name
remove_column :users, :hashed_password
remove_column :users, :salt
end


end


(2) user.rb modelの編集
入力されるパスワードを暗号化する=ハッシュ値を作るため、modelを編集します。
app>models>user.rb
class User < ActiveRecord::Base
belongs_to :song

attr_accessor :password, :password_confirmation
attr_protected :salt, :hashed_password

def self.authenticate(login_name, password)
user = find_by_login_name(login_name)
if user and user.hashed_password ==
hashed_password(password, user.salt)
user
else
nil
end
end

# ハッシュ値の生成
def self.hashed_password(password, salt)
Digest::SHA1.hexdigest(sprintf("%s%08d", password, salt))
end

end


(3) ymlの編集
フィクスチャデータを編集。
この三行を追加してください。

user.ymlに追加

login_name: user1(userごとに、ここは変える必要があります。)
hashed_password: <%= User.hashed_password('password', 12345678) %>
salt: 12345678


ここまで来たら、データの投入です。
rake db:migrate

(4) login controllerとview(ログインのindexページ)を作る
それでは、ログイン用のフォームを作りましょう。
$ ruby script/generate controller login index

login_controller.rb
class LoginController < ApplicationController

# ログイン
def login
login_name = params[:login_name]
password = params[:password]
user = User.authenticate(login_name, password)
if user
session[:user_id] = user.id
redirect_to :controller => 'users', :action => 'index'
flash[:notice] = "Logged in successfully"
else
session[:user_id] = nil
redirect_to :controller => 'login', :action => 'index'
flash[:warning] = 'ログイン失敗'
flash[:login_name] = login_name
end
end

# ログアウト
def logout
session[:user_id] = nil
redirect_to :controller => 'login', :action => 'index'
end

end


login>index.rhtml.erb

<% unless @current_user -%>
<div>
<h1>ログイン</h1>
<% form_tag '/login/login', :method => 'post' do %>
<%= hidden_field_tag 'from', request.request_uri %>
<table border="0">
<tr><td align="right">ユーザー名:</td>
<td><%= text_field_tag 'login_name', flash[:login_name],
:size => 16 %></td></tr>
<tr><td align="right">パスワード:</td>
<td><%= password_field_tag 'password', '',
:size => 16 %></td></tr>
<tr><td colspan="2" align="center">
<%= submit_tag 'ログイン' %>
</td></tr>
</table>
<% end %>
</div>
<% end -%>

<% if flash[:warning] -%>
<div id="warning">
<%= flash[:warning] %>
</div>
<% end -%>


(5) application.rbの編集
ログイン状態の確認を、すべてのコントローラーで使うため、application.rbを編集します。

controller>application.rb
class ApplicationController < ActionController::Base
helper :all

protect_from_forgery # :secret => 'b9df6040833a6d4befdb3d8b5fa52082'

before_filter :resume_session

private
# セッションの再開
def resume_session
return unless session[:user_id]

begin
@current_user = User.find(session[:user_id])
rescue ActiveRecord::RecordNotFound
session[:user_id] = nil
end
end

# ログインしていないユーザーをはじく
def block_non_users
unless @current_user
flash[:warning] = 'ログインが必要です。'
redirect_to :controller => 'login', :action => 'index'
return false
end
end
end


(6) users_controllerの編集

class UsersController < ApplicationControllerの下に以下のコードを追加します。
before_filter :block_non_users


これで完成!serverを立ち上げて、usersに接続しようとすると、ログインページに飛ばされるはずです。

0 件のコメント: