现在网络上有好多关于md5加密的破解方式,一些简单的密码例如123456,即使经过多重md5盐值加密仍旧会被破解。看了好多帖子之后发现了一个相比较md5更加方便的加密方式,但是他们又只介绍了怎么使用,具体怎么用在用户注册上却只字未提,这也让我想了好久才想到了怎么解决,为了给和我有同样困扰的小伙伴们更加直观的解决办法,同时为了解决大家时间,我自己编辑了一套简单好用的解决方案。话不多说直接上代码。
1、首先导入依赖
<!--Spring Security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、Security框架会自带一个登录的拦截页面,因为是测试,我选择了绕开登录页面
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
这样就不会被拦截,正常操作就ok了
3、我习惯性先从Controller层开始
@RestController
@Slf4j
public class JwtController {
@Autowired
private JwtService jwtService;
/**
* 用户注册 密码加密
* @param userDo
* @return
*/
@PostMapping("/newUser")
public Result newUser(@Valid @RequestBody UserDo userDo){
return jwtService.newUser(userDo);
}
4、Service以及impl
public interface JwtService {
Result newUser(UserDo userDo);
@Service
public class JwtServiceImpl implements JwtService {
@Autowired
private JwtMapper jwtMapper;
/**
* 用户加密添加
* @param userDo
* @return
*/
@Override
public Result newUser(UserDo userDo) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
try {
String password = userDo.getPassword();
String sc = passwordEncoder.encode(password);
userDo.setPassword(sc);
jwtMapper.newUser(userDo);
return new Result(200, true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(400, false, "用户名已存在");
}
}
5、Mapper以及xml
@Mapper
public interface JwtMapper {
Integer newUser(UserDo userDo);
<insert id="newUser">
insert into user (username,password,phone)
values (#{username},#{password},#{phone})
</insert>
这样就已经完成用户注册并且加密的过程了
但是!!但是!!但是!!
真正困扰我的问题来了,那就是用户该要怎么登陆呢,在之前使用md5的时候因为每次相同原始密码在加密之后生成的加密密码都是一致的,用户登录只需要将原始密码加密之后与存在数据库中的加密密码进行比对,如果一致就可以完成认证并且登录。但是经过Security的加密方法加密后的密码每次都是不同的。他只能通过原始密码和加密密码进行比对,如果一致返回true。可是加密密码在数据库里呀,我该怎么取出来,我想了好久,想到的解决办法就是将用户名设置唯一,然后登陆用到的参数分别是用户名和密码,先用用户名为参数,在数据库中取出已经加密的密码,在用输入的密码和加密密码进行比对,如果true,则返回用户信息及token。但是我总觉得这样的办法有漏洞,我自己还想不太明白,以下是代码部分,希望如果有大神看到可以指出问题所在,也希望能帮到和我有同样困扰的小伙伴们。
1、controller
/**
* 验证密码
* @param userAo
* @return
*/
@PostMapping("/sclogin")
public Result scLogin(@Valid @RequestBody UserAo userAo){
return jwtService.scLogin(userAo);
}
2、service以及impl
Result scLogin(UserAo userAo);
/**
* 用户登录
* @param userAo
* @return
*/
@Override
public Result scLogin(UserAo userAo) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String getp = null;
try {
getp = jwtMapper.lala(userAo.getUsername());
System.out.println(getp);
} catch (Exception e) {
e.printStackTrace();
return new Result(999,false,"不存在");
}
try {
if (passwordEncoder.matches(userAo.getPassword(),getp)){
userAo.setPassword(getp);
UserDo sc = jwtMapper.sc(userAo);
if (Objects.isNull(sc)) {
return new Result(400, false, "失败");
}
Map<String, String> map = new HashMap<>();
map.put(userAo.getUsername(), sc.getUsername());
String token = JwtUtils.getToken(map);
return new Result(200,true,sc +"\n"+ token);
}
return new Result(650,false,"账号或者密码错误");
} catch (Exception e) {
return new Result(800,false,"异常");
}
}
3、mapper及xml
UserDo sc(UserAo userAo);
String lala(String username);
<select id="sc" resultType="com.neusoft.pojo.Do.UserDo">
select *
from user
where username = #{username} and password = #{password}
</select>
<select id="lala" resultType="java.lang.String">
select password
from user
where username = #{username}
</select>