BCrypt密码加密

任何应用考虑到安全,绝不能明文的方式保存密码。密码应该通过哈希算法进行加密。有很多标准的算法比如SHA或者MD5,结合salt(盐)是一个不错的选择. Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用BCrypt强哈希方法来加密密码。
BCrypt强哈希方法 每次加密的结果都不一样。
(1)maven工程的pom引入依赖



 org.springframework.boot
 spring-boot-starter-security

(2)添加配置类
我们在添加了spring security依赖后,所有的地址都被spring security所控制了,我们目前只是需要用到BCrypt密码加密的部分,所以我们要添加一个配置类,配置为所有地址都可以匿名访问。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //authorizeRequests所有security全注解配置实现的开端,表示开始说明需要的权限
        //需要的权限两部分,第一部分是拦截的路径,第二部分访问该路径需要的权限
        //antMatchers 表示拦截的路径,permitAll任何权限都可以访问,直接放行所有
        //anyRequest任何的请求  authenticated认证后才能访问
        //.and().csrf().disable(); 固定写法,表示使csrf拦截失效.
        http
                .authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable();
    }
}

(3)修改maven工程的Application, 配置bean

@SpringBootApplication
public class UserApplication {

   public static void main(String[] args) {
      SpringApplication.run(UserApplication.class, args);
   }

   @Bean
   public IdWorker idWorkker(){
      return new IdWorker(1, 1);
   }

   @Bean
   public BCryptPasswordEncoder encoder(){
      return new BCryptPasswordEncoder();
   }
   //Spring Security
   //提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用   //BCrypt强
哈希方法来加密密码。

密码加密
maven工程的AdminService

//Spring Security
//提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用BCrypt强
//哈希方法来加密密码。
@Autowired
private BCryptPasswordEncoder encoder;/**
 * 增加
 * @param admin
 */
public void add(Admin admin) {
   admin.setId( idWorker.nextId()+"" );//主键值 
    //密码加密
   admin.setPassword(encoder.encode(admin.getPassword()));
   adminDao.save(admin);
}

登陆密码校验
(1)AdminDao增加方法定义

public interface AdminDao extends JpaRepository,JpaSpecificationExecutor{
//通过命名规则生成sql语句
    public Admin findByLoginname(String loginname);
}

(2)AdminService增加方法

@Autowired
private AdminDao adminDao;
@Autowired
private IdWorker idWorker;
//Spring Security
//提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用BCrypt强
//哈希方法来加密密码。
@Autowired
private BCryptPasswordEncoder encoder;

public Admin login(Admin admin) {
      //先根据用户名查询对象,
   Admin adminLogin = adminDao.findByLoginname(admin.getLoginname());
   //然后拿数据库中的密码和用户输入的密码匹配是否相同
   if(adminLogin!=null && encoder.matches(admin.getPassword(),adminLogin.getPassword())){
      //保证数据库中的对象中的密码和用户输入的密码是一致的  登录成功
      return adminLogin;
   }
   //登录失败
   return null;
}

(3)AdminController增加方法

@RequestMapping(value = "/login",method = RequestMethod.POST)
public Result login(@RequestBody Admin admin){
       Admin adminLogin = adminService.login(admin);
       if(adminLogin==null){
           return new Result(false,StatusCode.LOGINERROR,"登录失败");
   }
  
return new Result(true,StatusCode.OK,"登录成功");
       //登录的目的就是让前端和后端能通话
}


(4) 通过api测试

用户注册的密码加密和登录

修改service层的发送手机验证码方法public void sendSms(String mobile) {
   //生成六位数字随机数
   String checkcode = RandomStringUtils.randomNumeric(6);
   //向缓存中放一份
       redisTemplate.opsForValue().set("checkcode_"+mobile,checkcode,6, TimeUnit.HOURS);
//给用户发一份
   Map map = new HashMap<>();
   map.put("mobile",mobile);
   map.put("checkcode",checkcode);
       //rabbitTemplate.convertAndSend("sms",map); 注释掉这一行,不发送手机验证码,方面测试,只看控制台输入的验证码就可以
   //在控制台显示一份,方便测试
   System.out.println("验证码:"+checkcode);
}

修改maven工程的UserService 类的add方法,添加密码加密的逻辑

/**
 * 增加
 * @param user
 */
public void add(User user) {
   user.setId( idWorker.nextId()+"" );
   //密码加密
   user.setPassword(encoder.encode(user.getPassword()));
   user.setFollowcount(0);//关注数
   user.setFanscount(0);//粉丝数
   user.setOnline(0L);//在线时长
   user.setRegdate(new Date());//注册日期
   user.setUpdatedate(new Date());//更新日期
   user.setLastdate(new Date());//最后登陆日期
   userDao.save(user);
}

Controller层用户注册

/**
 * 发送短信验证码
 */
@RequestMapping(value = "/sendsms/{mobile}",method =RequestMethod.POST )
public Result sendSms(@PathVariable String mobile){
   userService.sendSms(mobile);
   return new Result(true,StatusCode.OK,"发送成功");
}

/**
 * 用户注册
 * @return
 */
@RequestMapping(value = "/register/{code}",method =RequestMethod.POST )
public Result regist(@PathVariable String code,@RequestBody User user){
       //得到缓存中的验证码
   String checkcodeRedis = (String) redisTemplate.opsForValue().get("checkcode_"+user.getMobile());
   if(checkcodeRedis.isEmpty()){
      return new Result(false, StatusCode.ERROR, "请先获取手机验证码");
   }
   if(!checkcodeRedis.equals(code)){
      return new Result(false, StatusCode.ERROR, "请输入正确的验证码");
   }
   userService.add(user);
   return new Result(true,StatusCode.OK,"注册成功");
}

测试运行后,添加数据 { "mobile": "13901238899" "password": "123123", } 
数据库中的密码为以下形式 $2a$10$a/EYRjdKwQ6zjr0/HJ6RR.rcA1dwv1ys7Uso1xShUaBWlIWTyJl5S 

用户登陆密码判断
(1)修改maven工程的UserDao接口,增加方法定义

public interface UserDao extends JpaRepository,JpaSpecificationExecutor{
 public User findByMobile(String mobile);
}

(2)修改mavenr工程的UserService 类,增加方法

public User login(String mobile, String password) {
   User user = userDao.findByMobile(mobile);
   if(user!=null && encoder.matches(password,user.getPassword())){
      return user;
   }
   return null;
}

修改maven工程的UserController类,增加login方法

@RequestMapping(value = "/login",method = RequestMethod.POST)
public  Result login(@RequestBody User user){
      user = userService.login(user.getMobile(),user.getPassword());
      if(user == null){
        return new Result(false,StatusCode.LOGINERROR,"登录失败");
   }
   return new Result(true,StatusCode.OK,"登录成功");
}

使用刚才新增加的账号进行测试,查看返回结果 进入api先获取验证码,再注册用户,再登录

你可能感兴趣的:(BCrypt密码加密)