黑马程序员JavaWeb开发教程
一、JWT - 简介
- 全程:JSON Web Token
- 定义了一种简介的、自包含的格式,用于在通信双方已json数据格式安全的传输信息。由于数字签名的存在,这额信息是可靠的
- 组成
- 第一部分:Header(头),激励令牌类型、签名算法等
- 第二部分:Payload(有效载荷),鞋带一些自定义信息、默认信息等
- 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。
- 场景:登录认证
- 登陆成功后,生成令牌
- 后续每个请求,都要携带JWT令牌,系统在每次请求处理之前,先校验令牌,通过后,再处理。
二、JWT - 生成
2.1 引入JWT依赖
<!-- JWT令牌技术依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
2.2 代码
- 在单元测试类中定义一个生成JWT令牌的方法进行测试
@Test
public void testGenJWT() {
Map<String, Object> claims = new HashMap<>();
claims.put("id", 1);
claims.put("name", "tom");
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, "itheima")//签名算法
.setClaims(claims)//自定义内容(载荷)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.compact();
System.out.println(jwt);
}
- 最终生成的JWT令牌
eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcxNjE3Nzg3OX0.64nmVM76BligepWLnE4Oh19gTQW8Rlr_UHBmjlLDZkk
三、 JWT令牌登录后下发
3.1 步骤
- 引入JWT令牌操作工具类
package com.itheima.mytlias.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static String signKey = "itheima";
private static Long expire = 43200000L;
/**
* 生成JWT令牌
* @param claims JWT第二部分负载 payload 中存储的内容
* @return
*/
public static String generateJwt(Map<String, Object> claims){
String jwt = Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS256, signKey)
.setExpiration(new Date(System.currentTimeMillis() + expire))
.compact();
return jwt;
}
/**
* 解析JWT令牌
* @param jwt JWT令牌
* @return JWT第二部分负载 payload 中存储的内容
*/
public static Claims parseJWT(String jwt){
Claims claims = Jwts.parser()
.setSigningKey(signKey)
.parseClaimsJws(jwt)
.getBody();
return claims;
}
}
- 登录完成后,调用工具类生成JWT令牌,并返回
package com.itheima.mytlias.controller;
import com.itheima.mytlias.pojo.Emp;
import com.itheima.mytlias.pojo.Result;
import com.itheima.mytlias.service.EmpService;
import com.itheima.mytlias.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
public class LoginController {
@Autowired
private EmpService empService;
/**
* 该接口用于修改员工的数据信息
* 请求方式为 POST
* 请求路径为/login
* 返回统一响应结果--JWT令牌
* 参数:
*
* @param emp @RequestBody --JSON格式的数据作为擦书,需要加上这个注解
* @return
*/
@PostMapping("/login")
public Result login(@RequestBody Emp emp) {
//打印日志
log.info("登录页面");
//调用service
Emp emp1 = empService.login(emp);
//返回结果
//如果登陆成功,则生成令牌,并下发令牌
if (emp1 != null) {
Map<String, Object> claims=new HashMap<>();
claims.put("id", emp.getId());
claims.put("name",emp.getName());
claims.put("username", emp.getUsername());
String s = JwtUtils.generateJwt(claims);
return Result.success(s);
}
return Result.error("用户名或者密码出错");
}
}