'Why validation not work for encoded password
In my project i add some validation for Signup form fields. While click on submit button password validation not check orignal password like @AAAzzz123
but it check encoded password like $2a$10$kUm6AxxH3SNSIoUtP6V7WOlFTIORTOILKDFGOP
and produce validation error message. Here down is my code.
Entity
public class User {
...
...
...
@Pattern(regexp = "(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[^\\da-zA-Z]).{8,15}$")
private String password;
}
Controller
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String resiterUser(@Valid @ModelAttribute("user") User user,
BindingResult result)
{
if(result.hasErrors())
{
return "signup";
}
// Problem is here
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepo.save(user);
return "redirect:/";
}
View
<form th:action="@{/register}" method="post">
<div class="form-outline mb-4">
<label class="form-label" for="form3Example4cg">Password</label>
<input type="password"
th:classappend="${#fields.hasErrors('password') ? 'is-invalid' : ''}"
class="form-control form-control-lg"
name="password" />
<div id="validation" class="text-danger" th:each="e: ${#fields.errors('password')}" th:text=${e}>
</div>
</div>
<div class="d-flex">
<button type="submit" class="btn bg-primary">Submit</button>
</div>
</form>
Solution 1:[1]
I solved my problem by the help of @OrangeDog
, Who give me the way how to solve this problem.
- Declare another variable
dummyPassword
withtransient
keyword which is temporary variable. - Here i am trying to validate the user entered password in Controller, If regular expression is match so,
dummyPassword
into encoded password and save into database otherwise got validation error
Entity:
public class User {
...
...
...
private String password;
@Pattern(regexp = "(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[^\\da-zA-Z]).{8,15}$")
private transient String dummyPassword;
}
In Controller set dummyPassword in orignal password
user.setPassword(bCryptPasswordEncoder.encode(user.getDummyPassword()));
Thymeleaf
<div class="form-outline mb-4">
<label class="form-label" for="form3Example4cg">Password</label>
<input type="password"
id="form3Example4cg"
th:classappend="${#fields.hasErrors('newPassword') ? 'is-invalid' : ''}"
class="form-control form-control-lg"
name="newPassword" />
<div class="text-danger" th:each="e: ${#fields.errors('newPassword')}" th:text=${e}>
</div>
</div>
Solution 2:[2]
There are two phases of validation - the MVC layer and the JPA layer. If you use the same model class for both layers then you can't use the same field for two different things.
You can separate them like this, for example:
@Entity
@Table(name = "USER")
public class User {
@Column(name = "password")
@Pattern(regexp = "^\\$2[aby]\\$.{56}$")
private String encodedPassword
// for form binding only
private transient String newPassword;
}
user.setEncodedPassword(bCryptPasswordEncoder.encode(user.getNewPassword()));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |