提供加密的配置文件
xx:
encoder:
crypt:
secret: ${random.uuid} # 随机的密钥,使用uuid
strength: 10 # 加密强度4~31,决定了密码和盐加密时的运算次数,超过10以后加密耗时会显著增加
解析配置文件,提供加密对象放到ioc容器(在业务层注入 BCryptPasswordEncoder 对象 )
@Data @Configuration @ConfigurationProperties(prefix = "xx.encoder.crypt") public class PasswordConfig { private int strength; private String secret; @Bean public BCryptPasswordEncoder passwordEncoder(){ // 利用密钥生成随机安全码 SecureRandom secureRandom = new SecureRandom(secret.getBytes()); // 初始化BCryptPasswordEncoder return new BCryptPasswordEncoder(strength, secureRandom); } }
controller层
@PostMapping("/register") public ResponseEntity<Void> register(@Valid User user, BindingResult result, //@Valid注解 + BindingResult result是Hibernat框架的,目的限制后台参数符合规则, @RequestParam("code") String code){ //不经过前端页面注册,直接后台注册,不符合规则报错走这里,自定义异常信息 if(result.hasErrors()){ String errorMsg = result.getFieldErrors().stream() .map(FieldError::getDefaultMessage) .collect(Collectors.joining("|")); throw new XxException(500,errorMsg); } userService.register(user,code); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); }
service层,要对密码进行加密后在录入数据库
@Autowired private StringRedisTemplate redisTemplate; @Autowired private BCryptPasswordEncoder passwordEncoder /** * 注册业务 * @param user * @param code */ public void register(User user, String code) { //获取redis中的验证码 String redisCode = redisTemplate.opsForValue().get(PHONE_CODE + user.getPhone()); //比对验证码是否正确 if(!StringUtils.equals(redisCode, code)){ //抛自定义异常; } //密码加密 user.setPassword(passwordEncoder.encode(user.getPassword())); //入库 int count = userMapper.insertSelective(user); if(count!=1){ //抛自定义异常; } }
在实体类中编写,前端接收的user参数校验
@Table(name = "tb_user") @Data public class User { @Id @KeySql(useGeneratedKeys = true) private Long id; @Size(min = 4,max = 16,message = "用户名不符合规范") private String username; @Size(min = 4,max = 16,message = "密码不符合规范") private String password; private String phone; private Date createTime; private Date updateTime; }