什么是JWT及在JAVA中如何使用?

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 在不使用JWT的情况下,我们一般选择的是cookie和session来进行服务鉴权(判断是否登录,是否具有某种权限),但是这是针对于只有一个客户端的情况下,现在客户端从pc端增长到了app端,现在就是多端访问了。
JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记。

也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他session数据。

此特性便于可伸缩性, 同时保证应用程序的安全

1、为什么使用JWT?

在不使用JWT的情况下,我们一般选择的是cookie和session来进行服务鉴权(判断是否登录,是否具有某种权限),但是这是针对于只有一个客户端的情况下,现在客户端从pc端增长到了app端,现在就是多端访问了。

在多端访问的情况下,可能就会存在一个问题,获取不到session和cookie。

同时在我们的服务端,通过集群的形式来进行搭建 ,也就是说服务端有多个共同提供服务,如果第一个服务器里记录session,那第二个服务如何获取呢?这些都是现实存在的问题, 那我们该如何解决?

这就引出了在微服务架构中如何进行服务鉴权的方案,这个方案就是 JWT.

2、JWT 的 格式

JWT就是一个字符串,经过加密处理与校验处理的字符串,形式为:A.B.C 三段,每一段中间通过 . 来隔开

  • A由JWT头部信息header加密得到
  • B由JWT用到的身份验证信息json数据加密得到
  • C由A和B加密得到,是校验部分

如果你还感觉不到清晰,这里有它的官方网站 : JSON Web Tokens - jwt.io

进入官方网站往下拉。

3、使用 JWT 就绝对安全 吗?

答案:

不安全

虽然我们看到JWT 经过多层加密。但是我们随便在网上找一个jwt 的 反解码工具,将JWT 处理后的字符串放进去。

大家可以发现,数据原封不动的还原了,所以在这里提醒大家对于敏感数据,比如用户的密码,账户的金额登录信息不应该存到JWT 字符串中,因为可以被解密。

4、JWT 的 鉴权 流程

JWT 如何判断是否登录呢?如何获取用户的用户信息呢?

这些内容就是JWT 的鉴权功能。

接下来我们来了解一下JWT 的 是如何鉴权的。

首先是登陆,客户端登陆的时候将用户的信息,用户名+密码发送到服务端。

服务端判断完之后,通过用户信息生成 JWT Token。

接着将生成的Token 响应给客户端,客户端再记录到本地。、

这个时候客户端有一个Toke 字符串里面有了用户信息,那么接下来客户端去访问其他接口,将Token,写入到请求头当中,发送到服务端,服务端就可以通过token来获取信息。

这里还要对Token 进行校验,看他是否是我们生成的,是否被进行了数据篡改。

如果全部没有问题,完成业务逻辑,最终响应给客户端。

当然啦,如果Token 有问题,就要响应给客户端,您未登录或者鉴权为通过。

这就是JWT 的鉴权流程了。

5、JWT 入门案例

接下来就带大家如何在JAVA 中使用JWT。

5.1 引入依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>

5.2 生成Token

public void testCreateToken() {
    //生成token
    //1、准备数据
    Map map = new HashMap();
    map.put("id",1);
    map.put("mobile","110");
    //2、使用JWT的工具类生成token
    long now = System.currentTimeMillis();
    String token = Jwts.builder()
            .signWith(SignatureAlgorithm.HS512, "yiqie") //指定加密算法
            .setClaims(map) //写入数据
            .setExpiration(new Date(now + 30000)) //失效时间
            .compact();
    System.out.println(token);
}

执行效果:

5.3 解析Token

public void testParseToken() {
    String token = "eyJhbGciOiJIUzUxMiJ9.eyJtb2JpbGUiOiIxMTAiLCJpZCI6MSwiZXhwIjoxNjY1MTI1MTkyfQ.0VU2gdRpJ1eEoDFev740VkVKrdT_bYecgB3qcw-ZtrhZstFbAFwhAhESXaHb-11AxG3AjZKEEWVoaBlkzFd6ug";
    try {
        Claims claims = Jwts.parser()
                .setSigningKey("yiqie")
                .parseClaimsJws(token)
                .getBody();
        Object id = claims.get("id");
        Object mobile = claims.get("mobile");
        System.out.println(id + "--" + mobile);
    }catch (ExpiredJwtException e) {
        System.out.println("token已过期");
    }catch (SignatureException e) {
        System.out.println("token不合法");
    }
}

5.4 工具类

对于JWT 的生成和解析,我们可以整合成一个工具类,便于我们自己后续使用。

public class JwtUtils {

    // TOKEN的有效期1小时(S)
    private static final int TOKEN_TIME_OUT = 1 * 3600;

    // 加密KEY
    private static final String TOKEN_SECRET = "yiqie";


    // 生成Token
    public static String getToken(Map params){
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, TOKEN_SECRET) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
                .addClaims(params)
                .compact();
    }


    /**
     * 获取Token中的claims信息
     */
    public static Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(TOKEN_SECRET)
                .parseClaimsJws(token).getBody();
    }


    /**
     * 是否有效 true-有效,false-失效
     */
    public static boolean verifyToken(String token) {
      
        if(StringUtils.isEmpty(token)) {
            return false;
        }
        
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey("yiqie")
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e) {
            return false;
        }

      return true;
    }
}
相关文章
|
4月前
|
NoSQL 安全 Java
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
|
7月前
|
JSON 前端开发 Java
|
7月前
|
JSON 前端开发 Java
JWT解密:探秘令牌魔法与Java的完美交互
JWT解密:探秘令牌魔法与Java的完美交互
91 0
JWT解密:探秘令牌魔法与Java的完美交互
|
7月前
|
开发框架 安全 Java
【Java专题_01】springboot+Shiro+Jwt整合方案
【Java专题_01】springboot+Shiro+Jwt整合方案
122 0
|
JSON 算法 Java
Java的jwt令牌原理
Java的jwt令牌原理
102 0
|
小程序 前端开发 Java
java如何利用JWT和注解,自定义参数的方式优雅实现小程序用户Id管理
在我们的开发项目中,经常需要用到用户ID,比如在小程序商城系统中,我们将商品加入购物车,这时前端就需要发送请求,携带上用户的ID。基本上很多种请求操作都需要携带用户ID,如果每个请求都需要我们往data中添加id的话,那样需要写很多重复代码,并且代码也不美观;所以我们可以利用JWT跟注解的方式来实现;
205 0
java202304java学习笔记第五十五天员工管理-生成JWT令牌
java202304java学习笔记第五十五天员工管理-生成JWT令牌
61 0
java202304java学习笔记第五十五天员工管理-生成JWT令牌2
java202304java学习笔记第五十五天员工管理-生成JWT令牌2
65 0
java202304java学习笔记第五十五天员工管理-JWT令牌介绍
java202304java学习笔记第五十五天员工管理-JWT令牌介绍
66 0
|
Java 应用服务中间件 Linux
Java 在linux或者tomcat下使用java.jwt.*这个类,报java.awt.headless 报空异常
在开发的过程中使用到了java.jwt.*包下的东西,在开发工具中使用没问题,但是如果到了单独的tomcat或Linux里就会报:java.awt.headless null空异常,再去配置java mv?非常麻烦,看我是如何解决的。
136 0