JJWT是一个提供端到端的JWT创建和验证的Java库

依赖

io.jsonwebtoken

jjwt

RELEASE

token的创建

setIssuedAt用于设置签发时间

signWith用于设置签名秘钥

JwtBuilder builder = Jwts.builder().setId(“111”)

.setSubject(“小明”)

.setIssuedAt(newDate())

.signWith(SignatureAlgorithm.HS256, “ld”);

String token = builder.compact();

token的解析

String token = “~~~”;

Claims claims = Jwts.parser().setSigningKey(“ld”).parseClaimsJws(token).getBody();

System.out.println(“id:” + claims.getId());

System.out.println(“subject:” + claims.getSubject());

System.out.println(“IssuedAt:” + claims.getIssuedAt());

token过期校验

long now = System.currentTimeMillis(); //当前时间

long exp = now + 1000 * 60; //过期时间为1分钟

JwtBuilder builder = Jwts.builder().setId(“111”)

.setSubject(“小明”)

.setIssuedAt(new Date())

.signWith(SignatureAlgorithm.HS256, “ld”)

.setExpiration(new Date(exp));

当未过期时可以正常读取

当过期时会引发 io.jsonwebtoken.ExpiredJwtException 异常

自定义claims

long now = System.currentTimeMillis(); //当前时间

long exp = now + 1000 * 60; //过期时间为1分钟

JwtBuilder builder = Jwts.builder().setId(“111”)

.setSubject(“小明”)

.setIssuedAt(new Date())

.signWith(SignatureAlgorithm.HS256, “ld”)

.setExpiration(new Date(exp))

.claim(“role”, “admin”);

获取:

claims.get(“role”)

示例

JWT工具类

@Data

public class JwtUtil {

private String key; //密钥加盐

private long ttl; //过期时间

/**

* 生成JWT

*/

public String createJWT(String id, String subject, String role) {

long nowMillis = System.currentTimeMillis();

Date now = new Date(nowMillis);

JwtBuilder builder = Jwts.builder().setId(id)

.setSubject(subject)

.setIssuedAt(now)

.signWith(SignatureAlgorithm.HS256, key).claim(“role”, role);

if (ttl > 0) {

builder.setExpiration(new Date(nowMillis + ttl));

}

return builder.compact();

}

/**

* 解析JWT

*/

public Claims parseJWT(String jwtStr) {

return Jwts.parser()

.setSigningKey(key)

.parseClaimsJws(jwtStr)

.getBody();

}

}

添加配置

jwt:

config:

key: littledonkey

ttl: 3600000

签发token

//判断是否密码是否正确

Admin loginAdmin = adminService.login(admin);

if (loginAdmin == null) {

return new Result(false, StatusCode.LOGINERROR, “登陆失败”);

}

//签发token

String token = jwtUtil.createJWT(admin.getId(), admin.getLoginname(), “admin”);

HashMap map = new HashMap<>();

map.put(“token”, token);

map.put(“role”, “admin”);

return new Result(true, StatusCode.OK, “登陆成功”, map);

使用拦截器方式实现token鉴权

org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,

继承此类,可以非常方便的实现自己的拦截器。

三个方法分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面):

在preHandle中,可以进行编码、安全控制等处理

在postHandle中,有机会修改ModelAndView

在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录

添加拦截器

@Component

public class TokenInterceptor implements HandlerInterceptor {

@Autowired

private JwtUtil jwtUtil;

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//获取请求头(如果有此请求头,表示token已经签发)

String header = request.getHeader(“tokenHeader”);

if (header != null || !””.equals(header)) {

//解析请求头(防止伪造token,token内容以”token “作为开头)

if (header.startsWith(“token “)) {

try {

Claims claims = jwtUtil.parseJWT(header.substring(6));

String role = (String) claims.get(“role”);

//为具有相关权限的用户添加权限到request域中

if (“admin”.equals(role)) {

//拿到”admin_token”头信息,表示当前角色是admin

request.setAttribute(“admin_token”, header.substring(6));

}

if (“user”.equals(role)) {

//拿到”user_token”头信息,表示当前角色是user

request.setAttribute(“user_token”, header.substring(6));

}

} catch (Exception e) {

throw new RuntimeException(“令牌不正确”);

}

}

}

//所有请求都通过,具体权限在service层判断

return true;

}

}

注册拦截器

@Configuration

public class InterceptorConfig extends WebMvcConfigurationSupport {

@Autowired

private TokenInterceptor tokenInterceptor;

@Override

protected void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(tokenInterceptor)

.addPathPatterns(“/**”)

.excludePathPatterns(“/login/**”);

}

}

service层验证

public void deleteById(String id) {

String admin_token = (String) request.getAttribute(“admin_token”);

if(admin_token == null || “”.equals(admin_token)){

throw new RuntimeException(“权限不足”);

}

adminDao.deleteById(id);

}


版权声明:本文为weixin_39647458原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39647458/article/details/114196770