2013-03-27 12 views
20

Mam opcję dodawania użytkownika w mojej aplikacji. Chciałbym przechować przepustkę użytkownika w formacie mieszania w bazie danych. Hasło jest przechowywane w postaci zwykłego tekstu w przykładowych kodach dołączonych do frameworka. Po kilku poszukiwaniach dowiedziałem się, że istnieje funkcja Crypto.encryptAES() zaimplementowana w play2, której można użyć do zabezpieczenia haseł.Zagraj w Framework 2 najlepszy sposób na przechowywanie skrótu hasła użytkownika

Moje pytanie brzmi: jakie jest najlepsze miejsce, aby z niego skorzystać? I jak z niego korzystać, aby stworzyć najbardziej podlegający konserwacji kod?

+1

Używam [jBCrypt] (http://mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m), który jest bardzo łatwy do zintegrowania z aplikacją. – maba

+0

dziękuję, ale naprawdę pytam, gdzie można nazwać funkcję haszowania. w modelu lub w kontrolerze? i jak? – zeal

+0

moim głównym problemem jest to, że nie mogę używać '@ PreUpdate' i' @ Prepersist' w ebean. – zeal

Odpowiedz

32

Osobiście zrobiłbym to w modelu User. Mam pobierające dla moich polach, więc w setPassword metody:

this.password = HashHelper.createPassword(password); 

Hashhelper jest tylko pojedyncza klasa dla wielu celów `mieszające rzeczy.

I Hashelper używam BCrypt, po prostu dodaj do Build.scala

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

A CryptoAPI wygląda następująco:

/** 
* 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()); 
} 

odszyfrowania wygląda następująco:

/** 
* 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); 
} 

Uwielbiam przechowywać moje kontrolery tak proste, jak to tylko możliwe, ponieważ widzę moich kontrolerów, tak jak kontrolerów ruchu między akcja użytkownika i model biznesowy (w moich modelach!).

+0

dziękuję za szczegółową odpowiedź, chciałbym też zachować kontrolerzy w czystości, myślę, że tego rodzaju logika powinna być zaimplementowana na poziomie modelu. Czytałem gdzieś, że muszę utworzyć getter i seter dla wszystkich atrybutów klasy, jeśli tworzę dla jednego. czy to prawda? – zeal

+0

Mimo że gra może działać z właściwościami publicznymi, wciąż wolę gettery i seterery i doświadczyłem dziwnego zachowania (wartość niewidoczna), gdy używa się ich mieszanych. Ale z getterami zawsze działa :-) – adis

+0

Wygląda na to, że mam build.sbt, a nie build.scala. Jaka jest właściwa inkantacja w tej sprawie? Dzięki! – GreenAsJade

4

znalazłem wiele prostsze rozwiązanie w internecie na ten adres: http://rny.io/playframework/bcrypt/2013/10/22/better-password-hashing-in-play-2.html

najpierw pobrać jbcrypt-xxx.jar na this adress.

W libraryDependencies w build.sbt dodać:

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

Jest to funkcja, aby utworzyć nowego użytkownika (znajdujący się w klasie modelu użytkownika):

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

I nadal w klasa użytkownika, funkcja do uwierzytelnienia:

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

I działa!

Powiązane problemy