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

依赖

        <dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>RELEASE</version>
</dependency>

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<String, String> 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,但未进行页面渲染)、返回处理(已经渲染了页面):

  1. 在preHandle中,可以进行编码、安全控制等处理
  2. 在postHandle中,有机会修改ModelAndView
  3. 在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);
}

Java 的 JJWT 实现 JWT的更多相关文章

  1. Spring Security + JJWT 实现 JWT 认证和授权

    关于 JJWT 的使用,可以参考之前的文章:JJWT 使用示例 一.鉴权过滤器 @Component public class JwtAuthenticationTokenFilter extends ...

  2. SpringBoot系列之前后端接口安全技术JWT

    @ 目录 1. 什么是JWT? 2. JWT令牌结构怎么样? 2.1 标头(Header) 2.2 有效载荷(Playload) 2.3 签名(Signature) 3. JWT原理简单介绍 4. J ...

  3. Java JWT: JSON Web Token

    Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand libr ...

  4. 各类JWT库(java)的使用与评价

    [搬运工] 出处:http://andaily.com/blog/?p=956 在 https://jwt.io/ 网站中收录有各类语言的JWT库实现(有关JWT详细介绍请访问 https://jwt ...

  5. 手写jwt验证,实现java和node无缝切换

    前言 前端时间和我朋友写了一个简易用户管理后台,功能其实很简单,涉及到的技术栈有:vue+elementUI,java+spring MVC以及node+egg,数据库用的mysql,简单方便. 一开 ...

  6. 通过webgoat-xxe、jwt学习Java代码审计

    WebGoat-JWT JWT Tokens 01 概念 本课程将介绍如何使用JSON Web Token(JWT)进行身份验证,以及在使用JWT时需要注意的常见陷阱. 目标 教授如何安全地实现令牌的 ...

  7. spring cloud实战与思考(五) JWT之携带敏感信息

    需求: 需要将一些敏感信息保存在JWT中,以便提高业务处理效率. 众所周知JWT协议RFC7519使用Base64Url对Header和Payload的Json字符串进行编解码.A JWT is re ...

  8. 基于jwt和角色的访问控制解决方案

    0,主要解决两个问题:1身份验证(防止httpclient拼接请求),2权限控制 1,身份验证使用jwt,在java就是jjwt jwt可以比较好的整合restful,对无状态客户端比较友好,(用se ...

  9. JWT+Interceptor实现无状态登录和鉴权

    无状态登录原理 先提一下啥是有状态登录 单台tomcat的情况下:编码的流程如下 前端提交表单里用户的输入的账号密码 后台接受,查数据库, 在数据库中找到用户的信息后,把用户的信息存放到session ...

随机推荐

  1. LeetCode 596. Classes More Than 5 Students (超过5名学生的课)

    题目标签: 题目给了我们 courses 表格,让我们找到 一个有至少5名学生的班级. 利用group by 把班级分类,在用Having count 来判断是否有5名,注意这里还需要用 distin ...

  2. LeetCode 595. Big Countries (大的国家)

    题目标签: 题目给了我们一个 world table,让我们找出 面积大于3 million square km 或者 人口大于 25 million. 直接用两个条件搜索. Java Solutio ...

  3. 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  4. spring data jpa使用 (转:http://www.manongjc.com/article/25284.html#four_1_7)

    Jap相关的使用 时间:2018-12-18 本文章向大家介绍Jap相关的使用,主要包括Jap相关的使用使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下. ...

  5. HashMap底层实现原理及面试问题

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  6. docker删除常见命令

    $ docker stop $(docker ps -a | grep "Exited" | awk '{print $1 }') //停止容器 1b7067e19d6f a840 ...

  7. iOS开发系列-iOS适配

    概述 发布iPhone X 系统版本为iOS11, 由于刘海屏原因需要对新的机型做适配. iPhone X safeArea iOS11苹果提出safeArea替代iOS7引入 topLayoutGu ...

  8. activemq设置后台管理用户名密码,及生产者消息密码

    activemq设置后台管理用户名密码,及生产者消息密码 1.修改conf/activemq.xml 在<broker>标签下,找到</shutdownHooks>标签.在这个 ...

  9. c#WinForm程序调用vsto动态库,已解决

    最近做一个vsto的项目,涉及到Form程序调用vsto动态库,弄了半天,搜了很多资料终于搞定了,把积累写下来备以后用.相关网址: https://stackoverflow.com/question ...

  10. 深度探索C++对象模型之第二章:构造函数语意学之成员初始值列表

    当我们需要设置class member的初值时,要么是经过member initialization list ,要么在construcotr内. 一.先讨论必须使用member initializa ...