尝试为与 Spring Boot 匹配的密码模式添加正则表达式

Trying to add a regex for password pattern matching with Spring Boot

我想为注册密码的用户添加模式匹配。在我的用户模型中,我有:

@Column
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$")
    private String password;

但是,当我去注册用户时,我收到了 400 Bad Request。

javax.validation.ConstraintViolationException: Validation failed for classes [com.practice.models.AppUser] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='must match \"^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$\"', propertyPath=password, rootBeanClass=class com.practice.models.AppUser, messageTemplate='{javax.validation.constraints.Pattern.message}'}\n]\n\tat 

可以用@Pattern注解来完成吗?它应该继续出现在模型上吗?

我的控制器端点如下所示:

@PostMapping("/register")
        public AppUser register(@Valid @RequestBody AppUser user) {
            return appUserService.createUser(user);
        }

这是我发送给注册的数据:

{
    "username": "Johnny",
    "email": "johnny@rosevideo.com",
    "password": "P@ssword123",
    "passwordConfirmation": "P@ssword123"
}

然后在我的服务层,我用 BCrypt 加密我的密码:

public AppUser createUser(AppUser appUser) {
        Optional<AppUser> existingUser = appUserRepo.findByUsername(appUser.getUsername());
        if (existingUser.isPresent()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with that username already exists");
        }

        if (!appUser.getPassword().equals(appUser.getPasswordConfirmation())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Passwords don't match");
        }

        String encodedPassword = bCryptPasswordEncoder.encode(appUser.getPassword());
        appUser.setPassword(encodedPassword);


        return appUserRepo.save(appUser);
    }
    ```

 

正则表达式有点偏差,您应该使用 \d 而不是 \\d:

^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$

使用以下正则表达式满足以下条件:

条件:

  • 最少 1 个大写字母。
  • 最少 1 个小写字母。
  • 最少 1 个特殊字符。
  • 最少 1 个数。
  • 最少 8 个字符。

正则表达式:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$@!%&*?])[A-Za-z\d#$@!%&*?]{8,}$

正在测试您的正则表达式,它似乎不起作用。我能够快速找到以下密码的正则表达式示例。

^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,16}$

此正则表达式仅在满足以下所有条件时才匹配:

  • 密码必须包含 1 个数字 (0-9)
  • 密码必须包含1个大写字母
  • 密码必须包含1个小写字母
  • 密码必须包含 1 个非字母数字
  • 密码为8-16个字符,无space

https://regex101.com/library/0bH043

这是另一个从字符串构建正则表达式的好网站: https://regex-generator.olafneumann.org/

当您在密码验证的同时使用密码加密时,通常会发生这种情况。基本上,您的应用目前正在 运行 对加密密码进行模式验证。

在没有额外配置的情况下,@Pattern 注释导致验证 运行 不仅在控制器中使用 @Valid 的地方,而且在调用 appUserRepo.save(appUser)。这意味着模式匹配是 运行 与散列密码,这很可能与您的模式不匹配。

如果您不想 运行 持久化验证,请将此行添加到您的 application.properties 文件中:

spring.jpa.properties.javax.persistence.validation.mode=none