Tavaszi biztonság - állítsa vissza jelszavát

Ez a cikk egy sorozat része: • Tavaszi biztonsági regisztráció bemutató

• A regisztráció folyamata tavaszi biztonsággal

• Regisztráció - Új fiók aktiválása e-mailben

• Tavaszi biztonsági regisztráció - Ellenőrző e-mail újraküldése

• Regisztráció a Spring Security-nél - Jelszó kódolás

• A Registration API RESTful lesz

• Tavaszi biztonság - Jelszó visszaállítása (aktuális cikk) • Regisztráció - A jelszó erőssége és szabályai

• Jelszavának frissítése

1. Áttekintés

Ebben az oktatóanyagban - folytatjuk a folyamatot Regisztráció a Spring Security-nél sorozat egy pillantással az alap "elfelejtettem a jelszavamat" funkció - így a felhasználó biztonságosan visszaállíthatja saját jelszavát, amikor arra szükség van.

2. Kérje a jelszó visszaállítását

A jelszó-visszaállítási folyamat általában akkor kezdődik, amikor a felhasználó valamilyen „reset” gombra kattint a Bejelentkezés oldalon. Ezután megkérhetjük a felhasználót az e-mail címére vagy más azonosító információra. A megerősítést követően létrehozhatunk egy tokent és e-mailt küldhetünk a felhasználónak.

Az alábbi ábra azt a folyamatot szemlélteti, amelyet ebben a cikkben megvalósítunk:

3. A Jelszó alaphelyzetbe állítási token

Kezdjük azzal, hogy létrehozunk egy PasswordResetToken entitás használja a felhasználó jelszavának alaphelyzetbe állításához:

@Entity public class PasswordResetToken {private static final int EXPIRATION = 60 * 24; @Id @GeneratedValue (strategy = GenerationType.AUTO) private Long id; privát String token; @OneToOne (targetEntity = User.class, fetch = FetchType.EAGER) @JoinColumn (nullable = false, name = "user_id") privát felhasználói felhasználó; privát Dátum lejárati dátum; }

Ha a jelszó visszaállítása elindul - létrejön egy token és egy speciális linket, amely ezt a tokent tartalmazza, e-mailben elküldjük a felhasználónak.

A token és a link csak egy meghatározott ideig érvényes (ebben a példában 24 óra).

4. forgotPassword.html

A folyamat első oldala az a "elfelejtettem a jelszavamat”Oldal - ahol a felhasználótól meg kell adni az e-mail címét a tényleges visszaállítási folyamat megkezdéséhez.

Tehát - készítsünk egy egyszerű forgotPassword.html e-mail címet kér a felhasználótól:

Visszaállítás

e-mail visszaállítás regisztráció bejelentkezés var serverContext = [[@ {/}]]; function resetPass () {var email = $ ("# email"). val (); $ .post (serverContext + "user / resetPassword", {email: email}, function (adatok) {window.location.href = serverContext + "login? message =" + data.message;}) .fail (function (adatok ) {if (data.responseJSON.error.indexOf ("MailError")> -1) {window.location.href = serverContext + "emailError.html";} else {window.location.href = serverContext + "login? üzenet = "+ data.responseJSON.message;}}); }

Most kapcsolódnunk kell ehhez az új „Jelszó visszaállítása”Oldal a bejelentkezési oldalról:

Visszaállítás

5. Hozza létre a PasswordResetToken

Kezdjük az új létrehozásával PasswordResetToken és küldje el e-mailben a felhasználónak:

@PostMapping ("/ user / resetPassword") public GenericResponse resetPassword (HttpServletRequest kérés, @RequestParam ("email") karakterlánc userEmail) {Felhasználó user = userService.findUserByEmail (userEmail); if (user == null) {dobjon új UserNotFoundException () -t; } String token = UUID.randomUUID (). ToString (); userService.createPasswordResetTokenForUser (felhasználó, token); mailSender.send (constructResetTokenEmail (getAppUrl (kérelem), request.getLocale (), token, felhasználó)); return new GenericResponse (messages.getMessage ("message.resetPasswordEmail", null, request.getLocale ())); }

És itt van a createPasswordResetTokenForUser () módszer:

public void createPasswordResetTokenForUser (Felhasználó felhasználó, String token) {PasswordResetToken myToken = új PasswordResetToken (token, felhasználó); passwordTokenRepository.save (myToken); }

És itt van a módszer constructResetTokenEmail () - e-mail küldésére használt a visszaállítási tokennel:

privát SimpleMailMessage constructResetTokenEmail (String contextPath, Locale locale, String token, Felhasználói felhasználó) {String url = contextPath + "/ user / changePassword? token =" + token; Karakterlánc üzenet = messages.getMessage ("message.resetPassword", null, területi beállítás); return constructEmail ("Jelszó visszaállítása", üzenet + "\ r \ n" + url, felhasználó); } privát SimpleMailMessage constructEmail (karakterlánc tantárgy, karakterlánc törzs, felhasználói felhasználó) {SimpleMailMessage email = új SimpleMailMessage (); email.setSubject (tárgy); email.setText (törzs); email.setTo (user.getEmail ()); email.setFrom (env.getProperty ("support.email")); visszatérő e-mail; }

Vegye figyelembe, hogyan használtunk egy egyszerű objektumot GenericResponse hogy képviseljük az ügyfélnek adott válaszunkat:

public class GenericResponse {private String üzenet; privát karakterlánc-hiba; public GenericResponse (String üzenet) {super (); this.message = üzenet; } public GenericResponse (String üzenet, String hiba) {super (); this.message = üzenet; this.error = hiba; }}

6. Ellenőrizze a PasswordResetToken

Miután a felhasználó rákattint az e-mailben található linkre, a user / changePassword végpont:

  • ellenőrzi, hogy a token érvényes-e és
  • bemutatja a felhasználónak a updatePassword oldalon, ahol új jelszót adhat meg

Ezután az új jelszót és a tokent továbbítja a user / savePassword végpont:

A felhasználó megkapja az egyedi linket tartalmazó e-mailt a jelszó visszaállításához, és rákattint a linkre:

@GetMapping ("/ user / changePassword") public String showChangePasswordPage (Területi beállítás, Modell modell, @RequestParam ("token") Karakterlánc) {String result = securityService.validatePasswordResetToken (token); if (eredmény! = null) {Karaktersorozat = üzenetek.getMessage ("auth.message." + eredmény, null, locale); return "redirect: /login.html? lang =" + locale.getLanguage () + "& message =" + üzenet; } else {model.addAttribute ("token", token); return "redirect: /updatePassword.html? lang =" + locale.getLanguage (); }}

És itt van a validatePasswordResetToken () módszer:

public String validatePasswordResetToken (String token) {final PasswordResetToken passToken = passwordTokenRepository.findByToken (token); return! isTokenFound (passToken)? "invalidToken": isTokenExpired (passToken)? "lejárt": null; } privát logikai isTokenFound (PasswordResetToken passToken) {return passToken! = null; } privát logikai isTokenExpired (PasswordResetToken passToken) {final Calendar cal = Calendar.getInstance (); return passToken.getExpiryDate (). before (cal.getTime ()); }

7. Módosítsa a jelszót

Ezen a ponton a felhasználó látja az egyszerűt Jelszó visszaállítása oldal - ahol az egyetlen lehetséges lehetőség a adja meg az új jelszót:

7.1. updatePassword.html

Visszaállítás

jelszó megerősítés token hiba subm var serverContext = [[@ {/}]]; $ (document) .ready (function () {$ ('form'). submit (function (event) {savePass (event);}); $ (": password"). keyup (function () {if ($ ("#password"). val ()! = $ ("# matchPassword"). val ()) {$ ("# globalError"). show (). html (/ * [[# {PasswordMatches.user}] ] * /);} else {$ ("# globalError"). html (""). hide ();}});}); function savePass (event) {event.preventDefault (); if ($ ("# password"). val ()! = $ ("# matchPassword"). val ()) {$ ("# globalError"). show (). html (/ * [[{{PasswordMatches. felhasználó}]] * /); Visszatérés; } var formData = $ ('forma'). serialize (); $ .post (serverContext + "user / savePassword", formData, function (adatok) {window.location.href = serverContext + "login? message =" + data.message;}) .fail (function (data) {if ( data.responseJSON.error.indexOf ("InternalError")> -1) {window.location.href = serverContext + "login? message =" + data.responseJSON.message;} else {var hibák = $ .parseJSON (adatok. responseJSON.message); $ .each (hibák, függvény (index, elem) {$ ("# globalError"). show (). html (item.defaultMessage);}); hibák = $ .parseJSON (data.responseJSON. hiba); $ .each (hibák, függvény (index, elem) {$ ("# globalError"). show (). append (item.defaultMessage + "

"); }); } }); }

Vegye figyelembe, hogy a reset tokent megmutatjuk, és POST paraméterként továbbítjuk a következő hívásban a jelszó mentése érdekében.

7.2. Mentse a jelszót

Végül, amikor az előző hozzászólási kérelmet elküldtük - az új felhasználói jelszó mentésre kerül:

@PostMapping ("/ user / savePassword") public GenericResponse savePassword (végleges területi beállítás, @Valid PasswordDto passwordDto) {String eredmény = securityUserService.validatePasswordResetToken (passwordDto.getToken ()); if (eredmény! = null) {return new GenericResponse (messages.getMessage ("auth.message." + eredmény, null, locale)); } Opcionális user = userService.getUserByPasswordResetToken (passwordDto.getToken ()); if (user.isPresent ()) {userService.changeUserPassword (user.get (), passwordDto.getNewPassword ()); return new GenericResponse (messages.getMessage ("message.resetPasswordSuc", null, locale)); } else {return new GenericResponse (messages.getMessage ("auth.message.invalid", null, locale)); }}

És itt van a changeUserPassword () módszer:

public void changeUserPassword (Felhasználó felhasználó, String jelszó) {user.setPassword (passwordEncoder.encode (jelszó)); repository.save (felhasználó); }

És a PasswordDto:

public class PasswordDto {private String oldPassword; privát String token; @ValidPassword private String newPassword; } 

8. Következtetés

Ebben a cikkben egy egyszerű, de nagyon hasznos funkciót valósítottunk meg egy érett hitelesítési folyamat számára - a saját felhasználó jelszavának visszaállításának lehetőségét a rendszer felhasználójaként.

A teljes végrehajtása ennek az oktatóanyagnak a GitHub projektje található meg - ez egy Eclipse alapú projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.

Következő » Regisztráció - Jelszó erőssége és szabályai « Előző A Registration API RESTful lesz