系列文章目录
第一章 sprintboot如何快速创建用户名密码校验机制
前言
在后台工程中一定会有登入功能,也就是用户需要输入用户名和密码,在前端首先会对输入的用户名和密码进行格式上的校验,然后前端将输入传给后端首先也需要进行格式校验,然后再判断用户名和密码是否有效,这个时候往往需要到数据库区的用户表中判断是否有这个用户
- 如果有这个用户,则校验通过,同时会返回一个token给前端,这个token就是之后前端和后端交互的凭证,有了这个凭证后端就不需要每一次都去数据库中判断请求的用户是否是有效用户以及这个用户是否登入,只需要去判断这个token是否有效即可
- 如果没有这个用户,则数据校验不通过,返回相应的错误给前端
一、创建验证控制器
@RestController
public class AuthController {
@Autowired
private JwtTokenUtil jwtTokenUtil;
//这个${jwt.auth-path}是去resources文件下的applicatoin.yml文件中取出对应的值
@RequestMapping(value = "${jwt.auth-path}")
public ResponseVO createAuthenticationToken(AuthRequest authRequest) {
boolean validate = false;
// 这边简化了,一般是去数据中查询时候有这个用户名和密码对应的数据,如果有的话返回对应用户的id,使
if("haha".equals(authRequest.getUserName()) || "haha".equals(authRequest.getPassword())) {
validate = true;
}
if (validate) {
// 利用工具列生成一个随机数,也可以称为盐值,用来创建对应的token
final String randomKey = jwtTokenUtil.getRandomKey();
//这变创建token其实只需要两个数据,一个用户对应的id,另一个就是盐值
//在工具类方法中我们也需要有根据token来获取对应用户的方法
final String token = jwtTokenUtil.generateToken(authRequest.getUserName()+authRequest.getPassword(), randomKey);
// 返回值
return ResponseVO.success(new AuthResponse(token, randomKey));
} else {
return ResponseVO.serviceFail("用户名或密码错误");
}
}
}
二、工具类介绍
@Component
public class JwtTokenUtil {
@Autowired
private JwtPropertise jwtProperties;
/**
* 生成token(通过用户名和签名时候用的随机数)
*/
public String generateToken(String userName, String randomKey) {
Map<String, Object> claims = new HashMap<>();
claims.put(jwtProperties.getMd5Key(), randomKey);
return doGenerateToken(claims, userName);
}
/**
* 生成token
*/
private String doGenerateToken(Map<String, Object> claims, String subject) {
final Date createdDate = new Date();
final Date expirationDate = new Date(createdDate.getTime() + jwtProperties.getExpiration() * 1000);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
.compact();
}
/**
* 获取混淆MD5签名用的随机字符串
*/
public String getRandomKey() {
return ToolUtil.getRandomString(6);
}
}
这里JwtPropertise 是Jwt的基础配置类,包含着需要用的数据。token就是用到Jwts类来创建的。这边的getRandomKey函数来创建随机数,是放在ToolUtil工具类中
/**
* 获取随机位数的字符串
*
* @author fengshuonan
* @Date 2017/8/24 14:09
*/
public static String getRandomString(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
获取随机数的方式就是创建一个字符数组,然后生成一个随机数,去数组中获取到对应的字符,这种方式也可以用作洗牌的,就是讲一个牌组打乱,只需要每一次取出的牌从原牌组中去除,然后更行牌组的数组大小即可。
三、业务数据类
我们都知道用于和数据库数据对应的可以用DO类表示,用于前端交互的可以用VO类来表示,然后在后端中表示业务数据类的可以用DTO类来表示,那么我们在进行用户认证时也会有相应的业务数据类
//请求类,只有用户名和密码
@Data
public class AuthRequest {
private String userName;
private String password;
}
//返回类,是token和randomKey的组合
@Data
public class AuthResponse implements Serializable {
private static final long serialVersionUID = 1250166508152483573L;
/**
* jwt token
*/
private final String token;
/**
* 用于客户端混淆md5加密
*/
private final String randomKey;
public AuthResponse(String token, String randomKey) {
this.token = token;
this.randomKey = randomKey;
}
}
总结
大致就是这样一个过程,具体代码已经放在github上了,感兴趣的小伙伴可以点击这查看。