BCrypt 在加密过程中会生成一个独特的盐,并将其与密码进行混合。每次加密时,盐都会不同,因此即使原始密码相同,每次加密生成的加密值也会不同。
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
package com.heima.common.bcrypt;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.security.SecureRandom;
@Configuration
public class PasswordConfig {
private int seedLength = 32;//随机秘钥的长度
/** * : 10 # 加密强度4~31,决定了密码和盐加密时的运算次数,超过10以后加密耗时会显著增加 */
private Integer strength = 10;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
// 加密前度,数字越大强度越大,越安全,越耗时
SecureRandom random = new SecureRandom(SecureRandom.getSeed(seedLength));
return new BCryptPasswordEncoder(strength, random);
}
}
登录需要验证用户名和密码,这里密码是使用Bcrypt加密的,所以验证的时候也需要使用Bcrypt来验证密码。
在admin服务中引入common中的bcrypt包
package com.heima.admin.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 初始化配置
*/
@Configuration
@ComponentScan({"com.heima.common.knife4j","com.heima.common.exception","com.heima.common.bcrypt"})
public class InitConfig {
}
package com.heima.admin.controller.v1;
import javax.validation.Valid;
import java.util.Map;
@RestController
public class AdLoginController {
@Autowired
private AdUserService adUserService;
/**
* 管理平台用户登录
* @param userLoginDto
* @return
*/
@PostMapping("/login/in")
public ResponseResult<Map<String,Object>> login(@Valid @RequestBody AdUserLoginDto userLoginDto){
return ResponseResult.ok(adUserService.login(userLoginDto));
}
}
package com.heima.admin.service;
public interface AdUserService extends IService<AdUser> {
Map<String,Object> login(AdUserLoginDto userLoginDto);
}
package com.heima.admin.service.impl;
@Slf4j
@Service
public class AdUserServiceImpl extends ServiceImpl<AdUserMapper, AdUser> implements AdUserService {
@Autowired
private BCryptPasswordEncoder encoder;
@Override
public Map<String, Object> login(AdUserLoginDto userLoginDto) {
// 构造查询条件
QueryWrapper<AdUser> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AdUser::getName,userLoginDto.getName());
// 查询
AdUser adUser = this.getOne(queryWrapper);
if(adUser == null){
// 如果根据用户名查询不到用户,报错
throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
}
// 使用BCryptPasswordEncoder提供的方法,比对密码
boolean b = encoder.matches(userLoginDto.getPassword(), adUser.getPassword());
if(!b){
// 如果密码不匹配,报错
throw new LeadException(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
}
// 设置token和用户信息返回
Map<String,Object> map = new HashMap<>();
String token = JwtUtils.generateTokenExpireInSeconds(adUser.getId(),3600);
map.put("token", token);
AdUserDto adUserDto = BeanHelper.copyProperties(adUser, AdUserDto.class);
map.put("user",adUserDto);
return map;
}
}
@PostMapping("/in")
public ResponseResult in(@Valid @RequestBody AdUserDto dto){
return adUserService.login(dto);
}