文章目录
目录
前言
一、什么是JWT ?
JSON Web Token是目前最流行的跨域认证解决方案,,适合前后端分离项目通过Restful API进行数据交互时进行身份认证. --JWT可以帮你生成一串字符串令牌。
组成:
一个token
分3部分,按顺序为
- 头部(
header
)数据格式是固定 - 载荷(
payload
)包含用户信息以及过期时间等---信息 - 签证(
signature
)加密
1.Header
Header 部分是一个 JSON 对象,描述 JWT 的元数据
{
"alg": "HS256",
"typ": "JWT"
}
2.Payload
Payload 部分也是一个 JSON 对象,用来存放==实际需要传递的数据==。JWT 规定了7个官方字段,供选用。
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
还可以自己定义字段
3.Signature
自己可以定义一个加密规则,然后让该工具类生成对应的加密。Algorithm.HMAC256(SIGN)
二、后端测试使用
1.加入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
2.编写工具类
package com.rcg.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.JWTVerifier;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* fetch data by show
*
* @param
* @create by:
* @description:
* @create time: 2022/11/23 14:29
* @return
*/
public class JwtUtil {
private static final String SIGN = "xxx"; //密钥
//1.通过jwt生成token字符串。
public static String createToken(Map<String, Object> params) {
Map<String, Object> head = new HashMap<>();
head.put("alg", "HS256");
head.put("typ", "JWT");
//定义颁发时间
Date iss = new Date();
//过期时间
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.MINUTE, 30);
Date expire = nowTime.getTime();
String token = JWT.create()
//指定头信息
.withHeader(head)
//载荷种的过期时间
.withExpiresAt(expire)
//颁发时间
.withIssuedAt(iss)
//颁发人
.withIssuer("xiaoming")
//自定义的载荷内容
.withClaim("userInfo", params)
//签名 加密
.sign(Algorithm.HMAC256(SIGN));
return token;
}
//2. 判断token是否合法
public static boolean verifyToken(String token) {
//通过秘钥解密判断
JWTVerifier build = JWT.require(Algorithm.HMAC256(SIGN)).build();
try {
DecodedJWT verify = build.verify(token);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//3. 解析token种的内容
public static Map<String, Object> decodeJWT(String token) {
Map<String, Object> userInfo = JWT.decode(token).getClaim("userInfo").asMap();
return userInfo;
}
}
3.在业务层使用,其他层正常写
@Override
public Result login(LoginVo loginVo) {
User loginUser = userMapper.findByUsernameAndPassword(loginVo.getUsername(), loginVo.getPassword());
if(loginUser!=null){
//保存对象信息并加密
HashMap<String, Object> map = new HashMap<>();
map.put("user",loginUser.getId());
String token = JwtUtil.createToken(map);
return new Result(2000,"登录成功",token);
}
return new Result(2004,"登录失败",2);
}
4.编写jwt判断mvc拦截器
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自己的拦截器,并设置拦截的请求路径
//addPathPatterns为拦截此请求路径的请求
//excludePathPatterns为不拦截此路径的请求
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/login/loginUser"
,"/doc.html","/student/update",
"/webjars/**","/student/add",
"/student/select","/student/delete","/student/one");
}
}
三、前端测试使用
1.添加axios请求拦截器
/*设置全局axios请求拦截处理器*/
axios.interceptors.request.use(config=>{
console.log(config)
//从浏览器的本地服务获取令牌信息
let token=localStorage.getItem("token");
//判断token 有token返回true
if (token){
config.headers.token=token;
console.log(config)
}
return config;
})
2.视图层页面使用
loginUser() {
this.$http.post("http://localhost:8088/login/loginUser",this.form).then(result=>{
console.log(result)
if (result.data.code === 2000) {
this.$message.success("登录成功")
//获取服务器响应的token值。保存LocalStorage
localStorage.setItem("token",result.data.data);
//跳转路由 不能使用location.href
this.$router.push("/home")
}else{
this.$message.error("账户或密码错误")
}
})
}