为什么我无法在 Spring Boot 和 Spring Security 中验证电子邮件?

问题描述 投票:0回答:1

我有两颗豆子:

CheckPassword
CheckEmail

@Service("CheckPassword")
@Primary
public class CheckPassword implements CheckStringInterface {

    private static final String regex_password = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$";

    @Override
    public boolean isStringValid(String rawPassword) {
        Pattern pattern = Pattern.compile(regex_password);
        Matcher matcher = pattern.matcher(rawPassword);
        return matcher.matches();
    }
}
@Service("CheckEmail")
public class CheckEmail implements CheckStringInterface {

    private static final String regex_password = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\\\.[A-Z]{2,6}$";

    @Override
    public boolean isStringValid(String rawPassword) {
        Pattern pattern = Pattern.compile(regex_password);
        Matcher matcher = pattern.matcher(rawPassword);
        return matcher.matches();
    }
}

我使用

@Qualifier
来选择我需要的bean,但为什么只有密码返回
true
,而电子邮件总是返回
false

@Qualifier("CheckPassword")
private final CheckStringInterface checkPasswordFormat;

@Qualifier("CheckEmail")
private final CheckStringInterface checkEmailFormat;

@Qualifier("EmailVerifyCode")
private final VerificationCodeManager verificationCodeManager;

@Value("${email_root}")
private String email_root;

private final SendMailTemplateService sendMailTemplateService;

private static final String template_verify_code_register = "templateVerifyCodeRegister";
private static String message_notification = "Use the code to verify this email: ";

@Transactional 
public Integer register(RegisterDTO registerDTO, HttpServletRequest request){
    if (userService.findByEmail(registerDTO.email()) == null) {
        if (checkPasswordFormat.isStringValid(registerDTO.password()) == false
        || checkEmailFormat.isStringValid(registerDTO.email()) == false) {
            log.info("Wrong Format {}", checkPasswordFormat.isStringValid(registerDTO.password()));
            log.info("Wrong Format {}", checkEmailFormat.isStringValid(registerDTO.email()));
           return 0; // Wrong format email or password
        }

        User user = new User();
        user.setEmail(registerDTO.email());
        user.setFullName(registerDTO.fullName());
        user.setPassword(registerDTO.password());
        user.setCreatedAt(Time.getTheTimeRightNow());
        user.setUserVerifyCode(verificationCodeManager.generateCode());
        user.setUserVerifyCodeExpirationTime(verificationCodeManager.codeExpiration());
        log.info("------> RegisterService | register: register with email {}", user.getEmail());
        createUser.create(user);
        sendMail(user, user.getUserVerifyCode());

        request.getSession().setAttribute("email", registerDTO.email());
        return 1; // Create successful
    } else {
        return 2; // Email already exists
    }
}

这是我在 Swagger 上测试 API 时使用的数据:

{
  "email": "[email protected]",
  "fullName": "abcdABCD",
  "password": "Password@1234"
}

我尝试更改为另一个正则表达式,但没有帮助。 当我登录时,我看到密码总是返回

true
,因为我输入了正确的格式,但电子邮件将返回
false
,格式正确和错误。

java regex spring-boot validation
1个回答
1
投票

这并不是一个真正与 springboot 或 spring security 相关的问题,而是一个与正则表达式相关的问题。

我在正则表达式电子邮件验证中发现两个主要问题:

  1. 您仅在电子邮件的正则表达式中包含大写字母(这将导致所有包含小写字母的字符串失败)
  2. 您在
    \\\\
    字符之前使用了
    .
    ,这将使正则表达式期望一个
    \
    (因为要在java中编写反斜杠,您需要
    \\
    ,所以另外两个
    \\
    实际上将转义它)并会导致被解释为特殊字符的点,表示“任何字符”

根据您当前的设置,

  • isStringValid("BONBON147852369@GMAIL\\.COM")
    返回
    true
  • isStringValid("BONBON147852369@GMAIL\\ACOM")
    返回
    true
  • isStringValid("bONBON147852369@GMAIL\\.COM")
    返回
    false

要修复代码,您只需在点前使用两个反斜杠(而不是 4 个),这样您就可以转义点字符,并且还需要使正则表达式也期望小写字母:

@Service("CheckEmail")
public class CheckEmail implements CheckStringInterface {
    private static final String regex_email = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$";
    @Override
    public boolean isStringValid(String rawEmail) {
        // alternative to Pattern.CASE_INSENSITIVE is to include a-z interval in your regex
        Pattern pattern = Pattern.compile(regex_email, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(rawEmail);
        return matcher.matches();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.