JWT根据维基百科的定义,JSON WEBToken(JWT,读作 [/dʒɒt/]),是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。

已签名JWT的压缩表示形式是一个由三部分组成的字符串,每部分由一个.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

每个部分都以base 64编码。第一部分是头部(header),至少需要指定用于签署JWT的算法。第二部分是身体(payload)。本部分包含此JWT的所有声明。最后一节是签名(signature)。它的计算方法是将标题和正文的组合通过标题中指定的算法进行计算。

1.头信息指定了该JWT使用的签名算法:

header ='{"alg":"HS256","typ":"JWT"}'

HS256 表示使用了 HMAC-SHA256 来生成签名。

2.消息体包含了JWT的意图:

payload ='{"loggedInAs":"admin","iat":1422779638}'//iat表示令牌生成的时间

3.未签名的令牌由base64url编码的头信息和消息体拼接而成(使用"."分隔),签名则通过私有的key计算而成:

key = 'secretkey'

unsignedToken = encodeBase64(header) + '.' +encodeBase64(payload)

signature = HMAC-SHA256(key, unsignedToken)

最后在未签名的令牌尾部拼接上base64url编码的签名(同样使用"."分隔)就是JWT了:

token = encodeBase64(header) + '.' +encodeBase64(payload) + '.' + encodeBase64(signature)

# token看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI

JWT常常被用作保护服务端的资源(resource),客户端通常将JWT通过HTTP的Authorizationheader发送给服务端,服务端使用自己保存的key计算、验证签名以判断该JWT是否可信:

Authorization: BearereyJhbGci*...<snip>...*yu5CSpyHI

测试代码:

public class JwtUtilsTest {
    /**
     * 创建jwt
     *
     * @param id
     * @param subject
     * @return
     * @throws Exception
    
*/
    public String createJWT(String id, String subject) throws Exception {
        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("uid", "1000000001");
        //生成签名的时候使用的秘钥secret
        SecretKey key = generalKey();
        //为payload添加各种标准声明和私有声明了
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)
                .setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                //  设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, key);

//  如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的

//  iss: jwt签发者
                //  Claims setIssuer(String var1);

//sub:jwt所面向的用户,这个是一个json格式的字符串,可以存放userid之类的,作为用户的唯一标志。
                //Claims setSubject(String var1);

//  aud: 接收jwt的一方
                //  Claims setAudience(String var1);

//  exp: jwt的过期时间,这个过期时间必须要大于签发时间
                //  Claims setExpiration(Date var1);

//  nbf: 定义在什么时间之前,该jwt都是不可用的.
                //  ClaimssetNotBefore(Date var1);

//  iat: jwt的签发时间
                //  Claims setIssuedAt(Date var1);

//  设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
                //  Claims setId(String var1);

return builder.compact();
    }

/**
     * 解密jwt
     *
     * @param jwt
     * @return
     * @throws Exception
    
*/
    public Claims parseJWT(String jwt) throws Exception {
        //签名秘钥,和生成的签名的秘钥一模一样
        SecretKey key = generalKey();
        //得到DefaultJwtParser
        Claims claims = Jwts.parser()
                //设置签名的秘钥
                .setSigningKey(key)
                //设置需要解析的jwt
                .parseClaimsJws(jwt).getBody();
        return claims;
    }

/**
     * 由字符串生成加密key
     *
     * @return
     */
    public SecretKey generalKey() {
        //本地配置文件中加密的密文JWT_SECRET_KEY
        String stringKey = "JWT_SECRET_KEY";
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        // 根据给定的字节数组使用AES加密算法构造一个密钥,使用 encodedKey中的始于且包含 0 到前 leng 个字节这是当然是所有。
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

public staticvoid main(String[] args) throws Exception {
        JwtUtilsTest utils = new JwtUtilsTest();
        String user = utils.createJWT("jwt", "{id:10001,name:zhangsan}");
        System.out.println(user);

String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxMDAwMDAwMDAxIiwic3ViIjoie2lkOjEwMDAxLG5hbWU6emhhbmdzYW59IiwiaWF0IjoxNTI4MzYyNzI1LCJqdGkiOiJqd3QifQ.Yw0iKM_yTdwUHbBFpMc9Gf2eVgpE9czw2RuG8soS_3c";
        Claims c = utils.parseJWT(jwt);
        //{uid=1000000001, sub={id:10001,name:zhangsan}, iat=1528362725, jti=jwt}
        System.out.println(c.toString());
    }
}

Java JWT:用于Java和Android的JSON Web令牌相关推荐

  1. jwt令牌_jwt-cli:用于解码JSON Web令牌(JWT令牌)的Shell库

    jwt令牌 当我开始经常需要解码JSON Web令牌时,我感到迫切需要编写允许我快速进行操作的程序. 有很多不错的选项,例如jwt.io ,但是一旦您需要执行此操作,它通常就会变得笨拙. 并且,如果您 ...

  2. jwt-cli:一个用于解码JSON Web令牌(JWT令牌)的Shell库

    当我开始经常需要解码JSON Web令牌时,我感到迫切需要编写允许我快速进行操作的程序. 有很多不错的选项,例如jwt.io ,但是一旦您需要执行此操作,它通常就会变得笨拙. 而且,如果您需要处理多个 ...

  3. 带有Spring Cloud Microservices的JSON Web令牌

    在Keyhole,我们已经发布了几个有关微服务的博客 . 我们已经讨论了微服务环境中使用的架构模式,例如服务发现和断路器 . 我们甚至在平台和工具上发布了博客,例如最近关于Service Fabric ...

  4. web api json_有关使用JSON Web令牌保护无服务器API的速成班

    web api json What a mouthful of a title. Wouldn't you agree? In this walkthrough you'll learn about ...

  5. 如何使用json开发web_如何通过使用JSON Web令牌简化应用程序的身份验证

    如何使用json开发web by Sudheesh Shetty 由Sudheesh Shetty 如何通过使用JSON Web令牌简化应用程序的身份验证 (How to simplify your ...

  6. web api json_使用JSON Web令牌对Node ES6 API进行身份验证

    web api json In this guide, we'll be implementing token based authentication in our own node.js A.P. ...

  7. 无效的JSON Web令牌

    本文翻译自:Invalidating JSON Web Tokens For a new node.js project I'm working on, I'm thinking about swit ...

  8. java sca_用于Java的SCA客户机和实现模型

    引言 SCA Java 实现模型提供了用于在 Java 中实现 SCA 组件的框架.组件实现可以提供服务,也可以充当其他服务的客户机.本文将说明 SCA Java 组件实现和非 SCA Java 组件 ...

  9. 10分钟了解JSON Web令牌(JWT)

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.虫虫今天给大家介绍JWT的原理和用法. 1.跨域身份验证 Internet服务无法与用户身份验证分开.一般过程如下. 1.用户 ...

最新文章

  1. 常考数据结构和算法:合并有序链表
  2. Spring OXM-XStream转换器
  3. 数据结构之顺序队列和链式队列常用的一些操作
  4. 高通宣布与蔚来合作下一代数字座舱技术
  5. java对象初始化顺序的简单验证
  6. MVC+EF 入门教程(四)
  7. 利用curl去hack他人博客
  8. Android进阶学习方法总结(内附阿里P7进阶学习全套资料)
  9. sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set的解决方案(linux)
  10. 湖北师范大学计信计科2018届期末实训EduCoder习题 (参考答案)
  11. 个人对东西方人开放的拙见。
  12. vue PC 端使用腾讯地图定位
  13. VS Code 的常用快捷键和插件(一)
  14. 十年牧码,我的平凡之路 | 程序员有话说
  15. Redis使用方法介绍
  16. Linux----软件安装及程序管理
  17. NLP基本功-文本相似度 | AI产品经理需要了解的AI技术通识
  18. 数字生活场景升级,智能音箱进入“存量战”
  19. 再来一个壁纸啊啊啊 嗷嗷
  20. vue 调用百度的UEditor富文本编辑器,本地运行没问题,打包后工具栏显示出错

热门文章

  1. 云计算 - OpenStack
  2. vue router name命名规范_超完整的Vue入门指导
  3. 联想用u盘重装系统步骤_联想笔记本重装win10系统教程
  4. 打开python的步骤_python RE 常见的打开方法
  5. 声明一个图书类(Java)
  6. Vue教程6【完结】【vue-router】路由,路由传参,编程式路由导航,缓存路由组件,路由守卫,路由模式,vue ui组件库
  7. 图标尺寸规范_作为刚入门的UI设计师,你需要懂哪些设计规范?
  8. 阿里开源混沌工程工具 ChaosBlade
  9. 17.1 MySQL主从介绍 17.2 准备工作 17.3 配置主 17.4 配置从 17.5 测试主从同步
  10. Windows 7合理虚拟内存RAMDISK提升运行性能