匹配编码密码字段 spring boot

Matching encoded password field spring boot

我目前正在学习 Spring-Boot 框架,并尝试按照 baledung.

页面上的指南创建匹配验证器的自定义字段

我的代码实际上和上面的页面一样,唯一不同的是我使用 BCryptPasswordEncoder 对密码进行了编码。

这是我的用户 class。

    @FieldsValueMatch.List({
        @FieldsValueMatch(
                field = "password",
                fieldMatch = "verifyPassword",
                message = "Passwords do not match!"
        )
})
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "User")
public class User implements UserDetails {
    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    @NotEmpty(message = "{firstname.notempty}")
    private String firstname;

    @Column(nullable = false)
    @NotEmpty(message = "{lastname.notempty}")
    private String lastname;

    @Column(nullable = false,unique = true)
    @NotEmpty(message = "{email.notempty}")
    @Email(message = "{email.notwellformed}")
    private String email;

    @Column(nullable = false)
    @NotEmpty(message = "{password.notempty}")
    @ValidPassword
    private String password;

    @NotEmpty(message = "{verifyPassword.notempty}")
    @Transient
    private String verifyPassword;

控制器:

    @PostMapping("/sign-up")
String signUp(@Valid User user, BindingResult bindingResult) {
    if (userService.userExists(user.getEmail())){
        bindingResult.rejectValue("email", "email.alreadyexists");
    }
    if(bindingResult.hasErrors()){
        return "sign-up";
    }
    user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
    userService.signUpUser(user);
    return "redirect:/sign-in";
}

注册用户方法:

    public void signUpUser(User user) {
    user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
    userRepository.save(user);
    final ConfirmationToken confirmationToken = new ConfirmationToken(user);
    confirmationTokenService.saveConfirmationToken(confirmationToken);
    sendConfirmationMail(user.getEmail(), confirmationToken.getConfirmationToken());
}

我收到以下错误:

    javax.validation.ConstraintViolationException: Validation failed for classes [com.project.project.entity.User] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Passwords do not match!', propertyPath=verifyPassword, rootBeanClass=class com.project.project.entity.User, messageTemplate='Passwords do not match!'}
    ConstraintViolationImpl{interpolatedMessage='Password must be no more than 30 characters in length.', propertyPath=password, rootBeanClass=class com.project.project.entity.User, messageTemplate='Password must be no more than 30 characters in length.'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:188) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:78) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:760) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:746) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]

我认为正在将编码密码与未编码的 verifyPassword 进行比较。这就是为什么我收到此错误或?我该如何解决? 如果我也对 verifyPassword 进行编码,我仍然会收到错误。

提前致谢。

30个字符的长度通常表示系统用户输入的密码长度不超过30个字符。但是,输入的密码在系统编码时将具有不同的长度。

发生此错误是因为您用于映射数据库实体的用户具有不超过 30 个字符的密码验证约束。对密码进行编码的过程可以修改密码的原始长度。因此出现错误。

您应该创建另一个 class UserDto,它可以从控制器访问,并将代表控制器 class 和系统的实际用户之间交换的信息键入密码。这个新的 UserDto 可以有 30 个字符的限制,而 User class 的数据库表示可以没有这样的限制,因为在数据库中密码将以不同的长度存储。

因此您将使用 UserDto class 来验证用户对系统的输入,并且您将使用 User class 来映射您的数据库记录在 java 对象内部遵循相对 table.

的结构