JWT令牌,前端(axiox)、后端操作
一、什么是JWT令牌
JWT简称JSON、Web、Token,也就是通过JSON形式作为web与应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。
JWT官网: https://jwt.io/
二、JWT的结构
token ====> header.payload.singnature
令牌的组成: 标头(header) 、有效负荷(payload) 、签名(singnature)
JWT通常所示:xxxxxx.yyyyyy.zzzzzz
- header:标头通常由两部分组成即令牌的类型(JWT)和使用的算法类型。【通常使用Base64编码组成JWT结构的第一部分】
{
"alg":"HS256",
"typ":"JWT"
}
- payload:有效负载,存储用户的相关的信息和其他数据的声明。【通常使用Base64编码组成JWT结构的第二部分】
{
"username":"Wangp",
"password":"123456" // 一般建议不要使用敏感数据
}
- singnature:签名,与前面两个部分生成JWT,该签名不能让其他人知道,是保证token不被串改,保证信息的安全。【通常使用Base64编码组成JWT结构的第二部分】
header+"."+payload+"."+singnature ---> 组成唯一的token
三、使用JWT令牌(后端)
- 引入JWT相关依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
- 创建工具类,生成、解析JWT令牌
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {
private String signKey; //JWT类型
private Long expire; //时间毫秒值
/**
* 生成JWT令牌
* @param claims map集合用于生成paylod
* @return
*/
public String generateJwt(Map<String, Object> claims) {
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, signKey)
.addClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + expire))
.compact();
return jwt;
}
/**
* 解析JWT令牌
* @param jwt 生成的JWT
* @return
*/
public Claims parseJWT(String jwt) {
Claims claims = Jwts.parser()
.setSigningKey(signKey)
.parseClaimsJws(jwt)
.getBody();
return claims;
}
}
- 常见的JWT异常
- SignatureVerificationException: 无效签名。
- TokenExpiredException: token过期。
- AlgorithmMismatchException: token算法不一致。
- InvalidClaimException: 失效payload异常
四、使用JWT令牌(前端 axiox)
按照流程:
1.提交登录表单,发送用户名和密码到后端,
2.后端验证成功后,会发送一个token给前端,
3.前端再拿这个token去请求需要用户权限访问,
4.后端验证toen,鉴权,返回相应结果。
当客户端登录到服务器时,服务器给出令牌并将其保存到客户端localStorage(或sessionStorage)。
每当客户端调用只能使用令牌访问的 api 时,客户端从 取回令牌localStorage,并将该令牌与授权标头(req.headers.[x-access-token]或req.headers.[authorization])一起发送到服务器。
- 登录接口:发送请求存储 jwt到 localStorage
login(){
## 在做登录接口时,需要把后端返回的JWT令牌存储到localStorage
这时就需要在添加如下两行代码进行存储
// 本地存储token
localStorage.setItem('token', res.data.data);
// 把token加入header里
axios.defaults.headers.common['X-token'] = res.data.data;
----------------------------------------------------------------
axios.post('/user/login', this.user).then(res => {
console.log(res.data.data);
if(res.data.flag) {
// 本地存储token
localStorage.setItem('token', res.data.data);
// 把token加入header里
axios.defaults.headers.common['X-token'] = res.data.data;
window.location.href='/backend/pages/main.html';
}else{
window.alert("Incorrect username or password !")
}
});
- 访问页面 发送 请求头 中的 jwt令牌到后端进行解析
## 访问页面时回发送 header中的token到 后端进行解析,解析成功即可访问
需要添加如下代码
{ headers: { token:localStorage.getItem('token') }
------------------------------------------------------------------
axios.get("/user/getUsername"
,{ headers: { token:localStorage.getItem('token') } }).then((res) => {
if(res.data.flag){
this.username = res.data.data;
} else {
window.location.href='/backend/login.html';
}
});