2014-10-22 2 views
1

Как реализовать механизм, который позволит войти в систему как любой пользователь, используя определенный пароль (так называемый главный пароль или супер пароль), который действителен для любого входа?Как реализовать безопасную аутентификацию Master/Super Password в Devise?

Это необходимо для административных целей и поддержки.

ответ

3

Если вам нужен мастер-пароль, вы не должны жестко указывать пароль в исходном коде и использовать полную проверку подлинности, предоставляемую Devise. Для этого вы можете добавить этот код в моделях:

class User 
    ... 
    # enables a Master Password check 
    def valid_password?(password) 
    return true if valid_master_password?(password) 
    super 
    end 

    # WARNING: Master User password changes require an application process restart 
    DEFAULT_MASTER_USER_EMAIL = '[email protected]' # config # SUGESTION: Move to an app configuration file 
    DEFAULT_MASTER_USER = self.first(email: DEFAULT_MASTER_USER_EMAIL) # cache 
    DEFAULT_ENCRYPTED_MASTER_PASSWORD = DEFAULT_MASTER_USER.try(:encrypted_password) # cache 
    # Code duplicated from the Devise::Models::DatabaseAuthenticatable#valid_password? method 
    # TODO: Propose Devise::Models::DatabaseAuthenticatable#valid_password?(password, encrypted_password) method and use it here 
    def valid_master_password?(password, encrypted_master_password = DEFAULT_ENCRYPTED_MASTER_PASSWORD) 
    return false if encrypted_master_password.blank? 
    bcrypt_salt = ::BCrypt::Password.new(encrypted_master_password).salt 
    bcrypt_password_hash = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt_salt) 
    Devise.secure_compare(bcrypt_password_hash, encrypted_master_password) 
    end 
    ... 
end 

Это должно быть безопасным, как ваш мастер (супер, администратора) пароль пользователя. Это позволит «только» дать основному пользователю больше мощности - возможность входа в систему, когда кто-либо использует свой пароль.

valid_master_password? метод может быть также использован для мастер-паролей настройки для групп пользователей и т.д., например, для администратора пользователей организаций:

class User 
    ... 
    # enables a Master Password check 
    def valid_password?(password) 
    return true if valid_master_password?(password) or 
        valid_master_password?(password, self.organization.admin_user.encrypted_password) 
    super 
    end 
    ... 
end 

Я также описал это в Devise Wiki.

Если вам нужен мастер-пароль, только в развитии, то это проще использовать этот код:

class User 
    ... 
    def valid_password?(password) 
    return true if Rails.env.development? and password == "THE_MASTER_PASSWORD" 
    super 
    end 
end 
+0

Не проблема при загрузке DEFAULT_MASTER_USER, поскольку вы не определили отношение пользователя в момент запроса? –

+0

@OleksandrKruk хороший вопрос. Этот код не дает мне никаких проблем. Почему эта работа может быть хорошим случаем для запроса в stackoverflow;) –

+0

@ SzymonJeż здесь я получаю ошибку "не может преобразовать Hash в Integer в" на этой строке DEFAULT_MASTER_USER = self.first (email: DEFAULT_MASTER_USER_EMAIL) # cache –

2

Я реализую это в производстве, но пришлось изменить эту строку:

DEFAULT_MASTER_USER = self.first(email: DEFAULT_MASTER_USER_EMAIL)

в

DEFAULT_MASTER_USER = self.find_by(email: DEFAULT_MASTER_USER_EMAIL)

Поскольку он не ищет пользователя по id, а скорее адрес электронной почты.

Смежные вопросы