パスワードを暗号化して格納
railsでユーザ認証を行うためのモデルを実装してみました。データベース上では、パスワードは平文ではなく、MD5で暗号化したかたちで格納されるよう実装しました。
テーブル定義と生成
生成されたmigrationのソースにテーブルの定義を行います。入力される平文パスワードのカラムは用意せず、暗号化したパスワードのカラムとsaltのカラムを用意します。
class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.column :name, :string, :limit => 32, :null => false t.column :crypted_password, :string, :limit => 32, :null => false t.column :salt, :string, :limit => 32, :null => false t.column :roll, :integer, :default => 0 t.timestamps end end
で、生成。
#rake db:migrate
モデルクラスの定義
Userモデルのクラスを定義します。
require 'digest/md5' class User < ActiveRecord::Base attr_accessor :password validates_uniqueness_of :name validates_presence_of :name, :password # 認証を行う。 def authoricate(name, password) return false if name != self.name return false if User.crypt_password(password, self.salt) != self.crypted_password true end # DB格納前のフック # saltと暗号化されたパスワードを生成 def before_create self.salt = User.new_salt self.crypted_password = User.crypt_password(self.password, self.salt) end private # パスワードを暗号化する def self.crypt_password(password, salt) Digest::MD5.hexdigest(password + salt) end # パスワード暗号化のためのsalt生成 def self.new_salt s = rand.to_s.tr('+', '.') s[0, if s.size > 32 then 32 else s.size end] end end
ユーザを登録する
railsのconsole環境で、ユーザを登録してみます。これは、暗号化しない場合と同様、平文のパスワードをモデルに入力してDBへのsaveを行うことになります。
nyaago@kyonkyon: 580 /Users/nyaago/workspace/cart$./script/console Loading development environment (Rails 2.0.2) >> user = User.new => #<User id: nil, name: nil, crypted_password: nil, salt: nil, roll: 0, created_at: nil, updated_at: nil> >> user.name = "moomin" => "moomin" >> user.password = "moomin" => "moomin" >> user.save => true >> user.save
登録、認証の確認
同じくrailsのconsole環境で、ユーザ名で検索してみてパスワードが暗号化されて登録されているか確認しまてみます。
つづいて、認証メソッドで認証できるか確認しました。登録したパスワードでauthoricateメソッドをコールするとtureが返され、別のパスワードでコールするとfalseが返されることを確認しました。
nyaago@kyonkyon: 583 /Users/nyaago/workspace/cart$./script/console Loading development environment (Rails 2.0.2) >> user = User.find_by_name('moomin') => #<User id: 1, name: "moomin", crypted_password: "4e64f0f60ba12cc0084844a78abce52f", salt: "0.709366042469232", roll: 0, created_at: "2008-09-04 15:47:24", updated_at: "2008-09-04 15:47:24"> >> user.authoricate('moomin', 'moomin') => true >> user.authoricate('moomin', 'moomi') => false
TODO
このモデルを使用した認証のコントローラーとVIEWを..