2013-03-27 3 views
20

У меня есть опция добавления пользователя в мое приложение. Я хотел бы сохранить пропуск пользователя в хэш-формате в базе данных. Пароль хранится в текстовом формате в примерах кодов, включенных в структуру. После некоторого поиска я узнал, что есть функция Crypto.encryptAES(), реализованная в play2, которая может использоваться для защиты паролей.Play Framework 2 лучший способ хранения хэша пароля пользователя

Мой вопрос: какое место лучше всего использовать? И как использовать его для создания наиболее удобного кода?

+1

Я использую [jBCrypt] (http://mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m), который очень легко интегрировать в ваше приложение. – maba

+0

спасибо, но я действительно спрашиваю, где назвать функцию хэширования. в модели или в контроллере? и как? – zeal

+0

моей главной проблемой является то, что я не могу использовать '@ PreUpdate' и' @ Prepersist' в ebean. – zeal

ответ

32

Лично я хотел бы сделать это в модели User. У меня есть добытчики для своих полей, так что в setPassword методы:

this.password = HashHelper.createPassword(password); 

Hashhelper это просто синглтон класс для нескольких целей хеширования вещей.

И в Hashelper я использую Bcrypt, просто добавьте следующее Build.scala

org.mindrot" % "jbcrypt" % "0.3m 

И криптовальную выглядит следующим образом:

/** 
* Create an encrypted password from a clear string. 
* 
* @param clearString 
*   the clear string 
* @return an encrypted password of the clear string 
* @throws AppException 
*    APP Exception, from NoSuchAlgorithmException 
*/ 
public static String createPassword(String clearString) throws AppException { 
    if (clearString == null) { 
     throw new AppException("empty.password"); 
    } 
    return BCrypt.hashpw(clearString, BCrypt.gensalt()); 
} 

и дешифрования выглядит следующим образом:

/** 
* Method to check if entered user password is the same as the one that is 
* stored (encrypted) in the database. 
* 
* @param candidate 
*   the clear text 
* @param encryptedPassword 
*   the encrypted password string to check. 
* @return true if the candidate matches, false otherwise. 
*/ 
public static boolean checkPassword(String candidate, String encryptedPassword) { 
    if (candidate == null) { 
     return false; 
    } 
    if (encryptedPassword == null) { 
     return false; 
    } 
    return BCrypt.checkpw(candidate, encryptedPassword); 
} 

Мне нравится держать мои контроллеры как можно более простыми, так как я вижу контроллеры так же, как контроллеры трафика между пользовательское действие и бизнес-модель (внутри моих моделей!).

+0

спасибо за подробный ответ, я бы хотел, чтобы контроллеры тоже чисты, я думаю, что такая логика должна быть реализована на уровне модели. я где-то читал, что я должен создать getter и setter для всех атрибутов класса, если я создам для одного. Это правда? – zeal

+0

Хотя игра может работать с общедоступными объектами, я по-прежнему предпочитаю геттеры и сеттеры, и я испытывал странное поведение (значение не видно) при их смешанном использовании. Но с геттерами он всегда работает :-) – adis

+0

Кажется, у меня есть build.sbt, а не build.scala. Какое правильное заклинание в этом случае? Благодаря! – GreenAsJade

4

Я нашел более простое решение в Интернете по этому адресу: http://rny.io/playframework/bcrypt/2013/10/22/better-password-hashing-in-play-2.html

сначала загрузить jbcrypt-xxx.jar на this adress.

В libraryDependencies в build.sbt, добавьте:

"org.mindrot" % "jbcrypt" % "0.3m" 

Это функция для создания нового пользователя (находится в модели класса пользователя):

public static User create(String userName, String password) { 
    User user = new User(); 
    user.userName = userName; 
    user.passwordHash = BCrypt.hashpw(password, BCrypt.gensalt()); 
    user.save(); 
    return user; 
    } 

И, по-прежнему в класс пользователя, функция для аутентификации:

public static User authenticate(String userName, String password) { 
    User user = User.find.where().eq("userName", userName).findUnique(); 
    if (user != null && BCrypt.checkpw(password, user.passwordHash)) { 
     return user; 
    } else { 
     return null; 
    } 

И это работает!

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