2

UserというDB列を持つRailsモデルを実装したいと思いますpassword。呼び出したときに...

user_instance.password = 'cleartext'

メソッドは、次のようにインスタンスに設定する前にクリアテキストをハッシュします。

Digest::SHA1.hexdigest(cleartext)

コールバックを使用してみましたが、問題は、pw が更新されていなくても、ユーザーが保存されるたびに pw がハッシュされることです。そのため、ハッシュと再ハッシュが何度も繰り返されます。

メソッドを再定義しようとしましたpassword=...

alias password= old_password=
def password=(cleartext)
  old_password=(Digest::SHA1.hexdigest(cleartext))
end

password=しかし、存在しないというエラーが発生しました。

4

4 に答える 4

8

参考までに、restful_authentication プラグインをチェックしてみてください。なぜあなた自身を転がすのですか?

act_as_authenticated の方法:

  1. データベース/モデルには「encrypted_pa​​ssword」という列があります
  2. password という仮想属性を作成する
  3. パスワードは find(..) では入力されないため、パスワードが空白の場合は暗号化しないでください
  4. パスワードが空白でない場合、それはユーザーがパスワードを入力したことを意味するので、先に進んで暗号化し、encrypted_pa​​ssword に入力します

コード スニップ (私のユーザー クラスからランダムにコピーして貼り付けるので、やみくもに貼り付けないでください):

require 'digest/sha1'
class User < ActiveRecord::Base

  # stuff

  # callback
  before_save   :encrypt_password
  attr_accessor :password

  # methods
    def encrypt_password
      return if password.blank?
      salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
      crypted_password = Digest::SHA1.hexdigest("--#{salt}--#{self.password}--")
    end
于 2009-02-16T21:11:15.650 に答える
1

まあ、セッターをオーバーライドできます:

def password=(value)
  self[:password] = Digest::SHA1.hexdigest(value)
end

そして、これは常に値を暗号化します。before_saveやattr_accessor は必要ありません。

于 2009-02-17T05:06:09.127 に答える
1

イーサンのコメントに応えて、仮想属性とは何か、仮想属性とは、Matt の attr_accessor :password のように、データベースにないものです。このようにして、ユーザーからの入力を受け入れることができますが、必ずしもそのフォームに保存する必要はありません。この例では、平文のパスワードを受け入れることができるようにしたいのですが、暗号化して保存したいと考えています。これを行うために、仮想属性 :password があり、データベースにそれを encrypted_pa​​ssword として保存します。

于 2009-02-17T01:41:39.650 に答える
1

ユーザーごとに (そのユーザーの作成時に) ランダムな n ビット値を選択し、それをハッシュするときにパスワードの先頭に追加することをお勧めします。

その理由は、誰かがあなたのデータベースを手に入れた場合、彼らはすぐにユーザーのパスワードを見ることができないだけでなく、2 人のユーザーが同じパスワードを持っているかどうかを確認することもできません (それらのユーザーの 1 人があなたのデータベースを取得した場合に重要です)。特定のクラスのハッシュ クラッキング攻撃 (レインボー テーブル) が難しくなります。

于 2009-02-17T08:24:55.593 に答える