Как получить has_secure_password в Rails 3.1 для правильной работы с OmniAuth - PullRequest
8 голосов
/ 21 сентября 2011

Я портирую проект с Rails 3 на 3.1.Моя система аутентификации была легко переключена на новый has_secure_password в ActiveRecord.Единственная проблема, с которой я сталкиваюсь, заключается в том, что я также использую OmniAuth, и у меня настроена система, поэтому, если пользователь регистрируется с помощью одного из поставщиков OmniAuth, для учетной записи не требуется пароль.Я не могу переопределить настройки проверки password_digest с помощью has_secure_password.В любом случае можно ли отключить эти проверки и написать свою собственную, или мне придется просто использовать мои старые написанные от руки функции bcrypt из моей версии Rails 3 сайта?

Ответы [ 2 ]

5 голосов
/ 28 сентября 2011

В итоге я вернулся к использованию пользовательских методов.Однако впоследствии я осознал, что должен был иметь возможность использовать обратный вызов before_validation для проверки условий, а затем, если они совпадают, установить для password_digest что-нибудь простое, например, «0».Таким образом, дайджест никогда не будет пустым, но в то же время он никогда не будет проверяться как правильный пароль, заставляя их входить в систему через OmniAuth.

Не стесняйтесь исправлять меня, если я ошибаюсь.

4 голосов
/ 30 сентября 2011

Скотт, твоя идея верна. Я боролся с этой проблемой безрезультатно. Я попытался переопределить 'has_secure_password', и он просто не будет работать. Неважно, где я застрял код.

Вместо этого у меня есть следующее:

class User < ActiveRecord::Base
  has_secure_password

  validates_presence_of :password, :on => :create, :if => :password_required

  # Associations
  has_many :authentications

  # Callbacks
  before_validation :no_password_omniauth

  # Gets set to true if the caller is trying to authenticate with omniauth.
  @called_omniauth = false

  # Build new omniauth users
  def apply_omniauth(omniauth)
    authentications.build(
    :provider => omniauth['provider'], 
    :uid => omniauth['uid'])
    self.first_name = omniauth['user_info']['first_name'] if self.first_name.blank?
    self.last_name = omniauth['user_info']['last_name'] if self.last_name.blank?
    self.email = omniauth['user_info']['email'] if omniauth['user_info']['email'] && self.email.blank?
    @called_omniauth = true
  end

  def password_required
    return false if @called_omniauth == true
    (authentications.empty? || !password.blank?)
  end

  private

  def no_password_omniauth
    self.password_digest = 0 unless password_required
  end

end

Метод apply_omniauth вызывается из контроллера, когда кто-то пытается аутентифицироваться или зарегистрироваться.

Спасибо за идею, что вы прибили это.

...