2013-03-27 61 views
20

我在我的應用中添加了一個用戶選項。我想將散列格式的用戶密碼存儲在數據庫中。密碼以純文本格式存儲在框架中包含的示例代碼中。 經過一番搜索之後,我發現play2中有一個Crypto.encryptAES()函數可以用來保護密碼。Play Framework 2存儲用戶密碼哈希的最佳方式

我的問題是最好的地方使用它?以及如何使用它來創建最可維護的代碼?

+1

我使用[jBCrypt](http://mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m),它很容易集成到您的應用程序中。 – maba

+0

謝謝,但我真正要問的是在哪裏調用散列函數。在模型中還是在控制器中?如何? – zeal

+0

我的主要問題是我不能在ebean中使用'@ PreUpdate'和'@ Prepersist'。 – zeal

回答

32

就我個人而言,我會在User模型中做到這一點。我有我的領域干將,所以在setPassword方法:

this.password = HashHelper.createPassword(password); 

Hashhelper只是爲了多目的散列東西一個單例類。

而在Hashelper我用BCrypt,只需添加以下到Build.scala

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

而且crypting樣子:

/** 
* 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

雖然遊戲可以使用公共屬性,但我仍然更喜歡getters和setter,並且在混合使用它們時遇到了奇怪的行爲(值不可見)。但與getters它總是工作:-) – adis

+0

我似乎有build.sbt,而不是build.scala。這種情況下正確的咒語是什麼?謝謝! – GreenAsJade

4

我發現在這個ADRESS在網絡上更簡單的解決方案: http://rny.io/playframework/bcrypt/2013/10/22/better-password-hashing-in-play-2.html

首先下載jbcrypt-xxx.jar在this adress

在build.sbt的libraryDependencies,添加:

"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; 
    } 

它的工作!