这一篇主要解决 前后端项目结合测试中出现的问题。
上一篇说完路由、前后端登录拦截器之后,有一个全局值status
,我们需要后端项目中给进行返回。
思路:
前端项目输入账号、密码之后,后端项目根据账号密码去数据库查找,找到符合的之后,生成一个含有用户信息的、唯一的标识值token。返回给前端。
解决方案
需要引入jwt,我们借助它生成token。
1.引入依赖
<!--jwt依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.创建jwtUtil工具类
package com.lbh.study.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
/**
* @ClassName JwtUtil
* @Description 令牌方法
* @Author liuBaiHui
* @Date 2023/10/14 22:44
* @Version 1.0
*/
public class JwtUtil {
// 有效期
public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000 一个小时
// 设置密钥明文
public static final String JWT_KEY = "baiHui";
/**
* @description: 生成UUID
* @author lbh
* @date 2023-10-16 21:39:46
* @version 1.0
*/
public static String getUUID(){
String token= UUID.randomUUID().toString().replace("-", "");
return token;
}
/**
* 1.生成jwt令牌,根据主体
* @param subject token中要存放的数据(json格式)
* @return
*/
public static String createJwt(String subject){
JwtBuilder builder = getJwtBuilder(subject,null,getUUID());
return builder.compact();
}
/**
* 2.生成令牌,根据主体、超时时间
* @param subject token中要存放的数据(json格式)
* @param ttlMillis token超时时间
* @return
*/
public static String createJWT(String subject, Long ttlMillis) {
JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
return builder.compact();
}
/**
* 3.生成jwt令牌,根据id, 主体,过期时间
* @param id
* @param subject
* @param ttlMillis
* @return
*/
public static String createJWT(String id, String subject, Long ttlMillis) {
JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间
return builder.compact();
}
/**
* 加密规则
* @param subject token中要存放的数据(json格式)
* @return
*/
private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid){
// 1.加密算法
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 2.密钥
SecretKey secretKey = generalKey();
// 3.系统当前时间
long nowMillis = System.currentTimeMillis();
// 4.转为SQL时间
Date now = new Date(nowMillis);
// 5.如果没有传入时间,则默认设置过期时间为 24小时
if(ttlMillis==null){
ttlMillis= JwtUtil.JWT_TTL;
}
// 6.过期时长
long expMillis = nowMillis + ttlMillis;
Date expDate = new Date(expMillis);
return Jwts.builder()
.setId(uuid) //唯一的ID
.setSubject(subject) // 主题 可以是JSON数据
.setIssuer("lbh") // 签发者
.setIssuedAt(now) // 签发时间
.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
.setExpiration(expDate);
}
/**
* 生成加密后的秘钥 secretKey
* @return
*/
public static SecretKey generalKey() {
// 1.使用 Base64加密算法进行计算
byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
/**
* 令牌解析
* @param jwt
* @return
* @throws Exception
*/
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = generalKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
}
// main方法,进行测试
public static void main(String[] args) throws Exception {
String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJmMzExMDUxZmYxNDU0MDgxODA0ODA0MmIwNmM3YjkxMCIsInN1YiI6IjEiLCJpc3MiOiJzZyIsImlhdCI6MTY5MzcwMTU5MiwiZXhwIjoxNjkzNzA1MTkyfQ.exZFFxFVJ2X4vzqreTZa_kkfbNNI8RiS_fJmRNYP2wU";
Claims claims = parseJWT(token);
System.out.println(claims);
}
}
3.LoginController方法修改
@PostMapping("/userLogin")
public ResultVO<String> userLogin(@RequestBody UserDto userDto){
// 1.登录接口
ResultVO<String> token = loginService.userLogin(userDto);
return token;
}
4.LoginServicelmpl
@Override
public ResultVO<String> userLogin(UserDto userDto) {
// 1.查询结果
SysUser sysUser = sysUserDao.selectByObject(userDto);
// 2.进行判断
if (!Objects.isNull(sysUser)){
// 3.根据userId生成jwt令牌
String userId = sysUser.getId();
// 4.调用jwtUtil方法,生成jwt,返回给前端
String jwt = JwtUtil.createJwt(userId);
ResultVO<String> success = ResultUtils.success(jwt);
return success;
}
return null;
}
5.前端中Vue和Vuex版本问题
在测试的过程中,发现引入的 store组件不能用,登录之后,发现始终拿不到token值,后来去百度查询了一下,是因为版本问题。参照图中的修改即可,修改完成之后,再进行测试,发现它能够使用到 store组件。
6.登录测试
输入账号密码,后端项目进行匹配,匹配到之后,生成一个唯一的值,token,返回给前端,前端进行判断之后,进行路由跳转。发现可以正常跳转了。
小结
到这里,登录功能终于就告一段落了,呼,真心不容易,考虑的点比较多,本想着记录一下,但是想想,也不能就这样糊弄过去,尽可能尽善尽美吧,各位大佬,可以点点关注、评论一下哇。谢谢咯。
之后的功能就会好很多了,慢慢来吧,