本文转载自凌大大的博客,原博客地址:[关于用户登录和权限验证功能的实现步骤](https://blog.csdn.net/wohaqiyi/article/details/79337981)
接上一篇文章shiro框架—关于用户登录和权限验证功能的实现步骤(四)
关于上一篇中,写出了关于shiro在springboot项目的配置步骤,还有几个简单的注意点没有说到。
1、用户名保证唯一性
这个应该很容易理解,对于一个系统来说,用户名是唯一的,不可重复,如果我们在注册用户时,比如随便起了一个用户名doudouchong
这样的用户。合理的方式是,在输入注册用户名后,页面应该马上调用一个接口,即查询当前用户名是否占用,如果占用应该提示已注册。在这样的前提下,就能保证用户名的唯一了。
2、密码入库要用暗文
在注册用户时,比如我们将注册的用户doudouchong
密码为123
,这样的信息保存到数据库用户表中,但是合理的情况下,你不能把这个密码明文123
保存到数据库中,你应该把暗文保存到数据库中,密码加密后的暗文,可以有多种方法来做到,比如我们项目中是用的下边的这个类:
package microservice.fpzj.core.util;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
public class PasswordUtil {
private String algorithmName = "md5"; //指定散列算法为MD5,还有别的算法如:SHA256、SHA1、SHA512
private int hashIterations = 2; //散列迭代次数 md5(md5(pwd)): new Md5Hash(pwd, salt, 2).toString()
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
public void setHashIterations(int hashIterations) {
this.hashIterations = hashIterations;
}
//加密:输入明文得到密文
public String encodePassword(String pwd, String salt) {
//user.setSalt(randomNumberGenerator.nextBytes().toHex());
String newPassword = new SimpleHash(
algorithmName,
pwd,
ByteSource.Util.bytes(salt),
hashIterations).toHex();
return newPassword;
}
public boolean verifyPassword(String targetPassword, String pwd, String salt){
String newPassword = this.encodePassword(targetPassword, salt);
if(newPassword.equals(pwd)){
return true;
}else{
return false;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
以上的 encodePassword
方法,即是加密密码明文的方法,该方法的参数除了明文密码,还有salt
,这个是盐,通过这个盐,可以对密码进一步加密,而这个盐,这里其实使用的是userid
,是通过UUID
获取的一个随机的字符串,作为用户表记录主键userid
的值,然后它们两个通过encodePassword
方法生成密码暗文,大体意思如下图所示:
通过传入123
和生成的uuid
值d9970477fb2349b984b1c98b8e559a91
两个参数,调用encodePassword
方法,即生成了密码暗文b7331bcddf29abef3a079ea0cb678f0e
,然后将该暗文作为用户表中的密码值存储到用户表中即可。
3、密码验证的逻辑
由于密码存入到用户表中是暗文,所以在验证中,不要忘记首先将用户输入的密码123
转换成暗文,然后再雨数据库用户表中存储的密码值进行比较。方法也是调用第二步中的encodePassword
,但是因为这个方法还需要盐,即salt
,而这个salt
值又来自于用户表中当前用户名的主键userid
值,所以,还要根据用户名查询到用户对象,取出userid
值,作为salt
,然后调用encodePassword
方法,这样才能转换成真正的密码暗文,如果salt
不对,生成的密码暗文肯定是不对的。
下一篇shiro框架—关于用户登录和权限验证功能的实现步骤(六)
本文转载自凌大大的博客,原博客地址:[关于用户登录和权限验证功能的实现步骤](https://blog.csdn.net/wohaqiyi/article/details/79337981)
接上一篇文章shiro框架—关于用户登录和权限验证功能的实现步骤(四)
关于上一篇中,写出了关于shiro在springboot项目的配置步骤,还有几个简单的注意点没有说到。
1、用户名保证唯一性
这个应该很容易理解,对于一个系统来说,用户名是唯一的,不可重复,如果我们在注册用户时,比如随便起了一个用户名doudouchong
这样的用户。合理的方式是,在输入注册用户名后,页面应该马上调用一个接口,即查询当前用户名是否占用,如果占用应该提示已注册。在这样的前提下,就能保证用户名的唯一了。
2、密码入库要用暗文
在注册用户时,比如我们将注册的用户doudouchong
密码为123
,这样的信息保存到数据库用户表中,但是合理的情况下,你不能把这个密码明文123
保存到数据库中,你应该把暗文保存到数据库中,密码加密后的暗文,可以有多种方法来做到,比如我们项目中是用的下边的这个类:
package microservice.fpzj.core.util;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
public class PasswordUtil {
private String algorithmName = "md5"; //指定散列算法为MD5,还有别的算法如:SHA256、SHA1、SHA512
private int hashIterations = 2; //散列迭代次数 md5(md5(pwd)): new Md5Hash(pwd, salt, 2).toString()
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
public void setHashIterations(int hashIterations) {
this.hashIterations = hashIterations;
}
//加密:输入明文得到密文
public String encodePassword(String pwd, String salt) {
//user.setSalt(randomNumberGenerator.nextBytes().toHex());
String newPassword = new SimpleHash(
algorithmName,
pwd,
ByteSource.Util.bytes(salt),
hashIterations).toHex();
return newPassword;
}
public boolean verifyPassword(String targetPassword, String pwd, String salt){
String newPassword = this.encodePassword(targetPassword, salt);
if(newPassword.equals(pwd)){
return true;
}else{
return false;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
以上的 encodePassword
方法,即是加密密码明文的方法,该方法的参数除了明文密码,还有salt
,这个是盐,通过这个盐,可以对密码进一步加密,而这个盐,这里其实使用的是userid
,是通过UUID
获取的一个随机的字符串,作为用户表记录主键userid
的值,然后它们两个通过encodePassword
方法生成密码暗文,大体意思如下图所示:
通过传入123
和生成的uuid
值d9970477fb2349b984b1c98b8e559a91
两个参数,调用encodePassword
方法,即生成了密码暗文b7331bcddf29abef3a079ea0cb678f0e
,然后将该暗文作为用户表中的密码值存储到用户表中即可。
3、密码验证的逻辑
由于密码存入到用户表中是暗文,所以在验证中,不要忘记首先将用户输入的密码123
转换成暗文,然后再雨数据库用户表中存储的密码值进行比较。方法也是调用第二步中的encodePassword
,但是因为这个方法还需要盐,即salt
,而这个salt
值又来自于用户表中当前用户名的主键userid
值,所以,还要根据用户名查询到用户对象,取出userid
值,作为salt
,然后调用encodePassword
方法,这样才能转换成真正的密码暗文,如果salt
不对,生成的密码暗文肯定是不对的。