会话跟踪 - 传统方案
-
cookie
- http协议支持的技术
- 缺点
- 移动端app中不支持
- 不安全,用户可以自己禁用cookie
- cookie不能跨域
-
session
- 存储在服务端,安全
- 缺点
- 服务端集群的场景下,无法使用session
- cookie的缺点
会话跟踪 - 现代方案
- jwt令牌
- 优点
- 支持pc,移动端
- 解决集群环境下的认证问题
- 解决服务器的存储压力
- 缺点
- 需要自己实现
- 优点
JWT令牌的实现
代码实现
- 测试代码
java
@Test
public void testGernateJWT(){
Map<String, Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("username","gaofeng");
String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "gaofeng")
.setClaims(claims).setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)).compact();//自定义内容
log.info("jwt:{}", jwt);
this.testParseJWT(jwt);
}
@Test
public void testParseJWT(String jwt) {
Claims claims = Jwts.parser().setSigningKey("gaofeng")
.parseClaimsJws(jwt).getBody();
log.info("id:{}", claims.get("id"));
log.info("username:{}", claims.get("username"));
log.info("expiration:{}", claims.getExpiration());
}
- 封装jwt方法
java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class JwtUtils {
private static String signKey = "gaofeng";
private static Integer expire = 1000 * 60 * 30;
public static String gernateJWT(Map<String,Object> claims){
String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, signKey)
.setClaims(claims).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();//自定义内容
log.info("jwt:{}", jwt);
return jwt;
}
public static Claims parseJWT(String jwt) {
Claims claims = Jwts.parser().setSigningKey(signKey)
.parseClaimsJws(jwt).getBody();
log.info("id:{}", claims.get("id"));
log.info("username:{}", claims.get("username"));
log.info("expiration:{}", claims.getExpiration());
return claims;
}
}
- controller代码
java
@RestController
@Slf4j
public class LoginController {
@Autowired
private EmpService empService;
@PostMapping("/login")
public Result login(@RequestBody Emp emp){
log.info("登录信息:{}", emp);
Emp e = empService.login(emp);
if(e != null){
//登录成功,生成jwt,并下发
Map<String, Object> claims = new HashMap<>();
claims.put("id", emp.getId());
claims.put("username", emp.getUsername());
claims.put("name", emp.getName());
String jwt = JwtUtils.gernateJWT(claims);
return Result.success(jwt);
}
return Result.error("登录失败,账户或密码错误");
}
}
解析jwt网站:https://www.bejson.com/jwt/
页面登录后返回的结果