1

UserRails 4.0 アプリで使用するときにのパスワードを自動的に生成したいと思いますhas_secure_password(注: がないのはそのためattr_accessorです)。

私は非常に単純なUserモデルを持っています:

class User < ActiveRecord::Base
  has_secure_password
  validates :email, presence: true
end

通話で使用SecureRandom.hex(8)してパスワードを作成する方法を知りたいです。before_saveそれを色々と追加before_save { self.password = SecureRandom.hex(8) }してみたのですが、Railsコンソールに保存しようとすると、password空ですと出てしまいました。

どんな助けでも大歓迎です!

4

2 に答える 2

0

コールバックは便利なソリューションですが、必要な複雑なレイヤーを追加しているため、テストが難しくなります。

別のアプローチは、ユーザーの「上」に位置するクラスを作成することです。これが最善の解決策であるとは言いませんが、私が便利だと思ったものです。このクラスは次のクラスを継承していることに注意してくださいUser

# user_with_default_password.rb
class UserWithDefaultPassword < User
  def initialize(options = {})
    random_password = SecureRandom.hex(8)

    options[:password] = random_password

    # If creating a user with confirmation requirements
    options[:password_confirmation] = random_password

    # Call User.new(options)
    super(options)
  end
end

使用法:

user = UserWithDefaultPassword.new() # => user.password = "ajfladfjkf..."

これの利点は、しばしばテストを遅くするコールバックを強制することなく User と UserWithDefaultPassword をテストできることです。

User.new()また、必要に応じて、代わりに を使用するだけで、デフォルトのパスワードを使用して、または使用せずにユーザーを作成できますUserWithDefaultPassword.new()。これにより、柔軟性が向上し、テストが改善されます。

更新: 2014-04-21

また、ランダムなパスワードを作成するためのコードなどを、(Rails フレームワークをロードせずに) すばやくテストできる別のクラスに抽出することをお勧めします。以下は、これらの単純なタスクのいくつかを実行するために最近作成したクラスです。

#==================================================
# Generates random/unique strings/tokens/IDs
# See: http://ruby-doc.org/stdlib-2.0.0/libdoc/securerandom/rdoc/SecureRandom.html
# See: http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec-signin_success
#==================================================
class Generator
  require "securerandom"

  # General-purpose encryption using SHA1 instead of bcrypt; faster but LESS SECURE than bcrypt
  # (do not use for extremely sensitive data such as passwords)
  def self.encrypt(value)
    if value.nil? || value.empty?
      ""
    else
      Digest::SHA1.hexdigest(value.to_s)
    end
  end

  # Although a UUID would work as an auto-generated password,
  # it just seems more appropriate to make the password a random
  # string.
  def self.random_password
    SecureRandom.urlsafe_base64(32)
  end

  # Used as a random, unique token
  def self.uuid
    SecureRandom.uuid
  end

  # Returns random number as string for admin 2-step authentication
  def self.verification_code(length)
    value = ""

    if length.nil? || length.zero?
      length = 6
    elsif length > 20
      length = 20
    end

    length.times do |num|
      value += SecureRandom.random_number(10).to_s
    end

    value
  end
end

使用法:Generator.random_password # => "abc123..."

大きな利点は、Rails フレームワークをロードせずにランダム パスワードの作成をテストできることです。これにより、ロード時間が 3 ~ 4 秒短縮されます。これは (ほとんどの場合) Rails 4.1 で解決されます。Rails 4.1 では Spring を使用してテスト用にアプリをプリロードしますが、Rails 4.1 を使用していない (または Spring gem を使用している) 場合は、これがより良い解決策です。

于 2014-04-21T19:58:36.767 に答える