JWT全面解读

    • JWT全面解读
  • 前言
  • JWT基本使用
    • 在pom.xml引入java-jwt
    • 示例如下
  • 概念介绍
    • JWT消息构成
    • 头部
    • playload
      • 标准中注册的声明 (建议但不强制使用)
      • 自定义数据
    • 签名signature
  • JJWT
    • 引入
    • 使用方法
    • 生成token
    • 解析token

前言

JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

优点是在分布式系统中,很好地解决了单点登录问题,很容易解决了session共享的问题。
缺点是无法作废已颁布的令牌/不易应对数据过期。

可能习惯了redis保存session,使用shiro做登陆,突然使用JWT有点不适应,因为太简单了,我个人不是很建议使用,还是那句话,你的选择权有多大,你有学多少知识。

JWT基本使用

在pom.xml引入java-jwt

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version>
</dependency>

Gradle下依赖
compile 'com.auth0:java-jwt:3.4.0'

示例如下

package yui.ui.web.sys.controller;import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import com.alibaba.druid.util.StringUtils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;public class Test {/*** APP登录Token的生成和解析* *//** token秘钥,请勿泄露,请勿随便修改 backups:JKKLJOoasdlfj */public static final String SECRET = "JKKLJOoasdlfj";/** token 过期时间: 10天 */public static final int calendarField = Calendar.DATE;public static final int calendarInterval = 10;/*** JWT生成Token.<br/>* * JWT构成: header, payload, signature* * @param user_id*            登录成功后用户user_id, 参数user_id不可传空*/public static String createToken(Long user_id) throws Exception {Date iatDate = new Date();// expire timeCalendar nowTime = Calendar.getInstance();nowTime.add(calendarField, calendarInterval);Date expiresDate = nowTime.getTime();// header MapMap<String, Object> map = new HashMap<>();map.put("alg", "HS256");map.put("typ", "JWT");// build token// param backups {iss:Service, aud:APP}String token = JWT.create().withHeader(map) // header.withClaim("iss", "Service") // payload.withClaim("aud", "APP").withClaim("user_id", null == user_id ? null : user_id.toString()).withIssuedAt(iatDate) // sign time.withExpiresAt(expiresDate) // expire time.sign(Algorithm.HMAC256(SECRET)); // signaturereturn token;}/*** 解密Token* * @param token* @return* @throws Exception*/public static Map<String, Claim> verifyToken(String token) {DecodedJWT jwt = null;try {JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();jwt = verifier.verify(token);} catch (Exception e) {// e.printStackTrace();// token 校验失败, 抛出Token验证非法异常}return jwt.getClaims();}/*** 根据Token获取user_id* * @param token* @return user_id*/public static Long getAppUID(String token) {Map<String, Claim> claims = verifyToken(token);Claim user_id_claim = claims.get("user_id");if (null == user_id_claim || StringUtils.isEmpty(user_id_claim.asString())) {// token 校验失败, 抛出Token验证非法异常}return Long.valueOf(user_id_claim.asString());}
}

最终存放的数据在JWT内部的实体claims里。它是存放数据的地方

概念介绍

JWT消息构成

一个token分3部分,按顺序为

  • 头部(header)
  • 其为载荷(payload)
  • 签证(signature)
    由三部分生成token
    3部分之间用“.”号做分隔。例如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    验证koten地址

头部

Jwt的头部承载两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法 通常直接使用 HMAC SHA256
    JWT里验证和签名使用的算法,可选择下面的。
JWS 算法名称 描述
HS256 HMAC256 HMAC with SHA-256
HS384 HMAC384 HMAC with SHA-384
HS512 HMAC512 HMAC with SHA-512
RS256 RSA256 RSASSA-PKCS1-v1_5 with SHA-256
RS384 RSA384 RSASSA-PKCS1-v1_5 with SHA-384
RS512 RSA512 RSASSA-PKCS1-v1_5 with SHA-512
ES256 ECDSA256 ECDSA with curve P-256 and SHA-256
ES384 ECDSA384 ECDSA with curve P-384 and SHA-384
ES512 ECDSA512 ECDSA with curve P-521 and SHA-512

使用代码如下

// header Map
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");

playload

载荷就是存放有效信息的地方。基本上填2种类型数据

-标准中注册的声明的数据
-自定义数据
由这2部分内部做base64加密。最张数据进入JWT的chaims里存放。

标准中注册的声明 (建议但不强制使用)

iss: jwt签发者sub: jwt所面向的用户aud: 接收jwt的一方exp: jwt的过期时间,这个过期时间必须要大于签发时间nbf: 定义在什么时间之前,该jwt都是不可用的.iat: jwt的签发时间 jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

使用方法

 JWT.create().withHeader(map) // header.withClaim("iss", "Service") // payload.withClaim("aud", "APP").withIssuedAt(iatDate) // sign time.withExpiresAt(expiresDate) // expire time

自定义数据

这个就比较简单,存放我们想放在token中存放的key-value值
使用方法

 JWT.create().withHeader(map) // header.withClaim("name", "cy") // payload.withClaim("user_id", "11222");

签名signature

jwt的第三部分是一个签证信息,这个签证信息算法如下:
base64UrlEncode(header) + "." + base64UrlEncode(payload)+your-256-bit-secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

基本上至此,JWT的API相关知识已经学完了,但是API不够有好,不停的用withClaim放数据。不够友好。下面推荐一款框架,相当于对JWT的实现框架

JJWT

它是为了更友好在JVM上使用JWT,是基本于JWT, JWS, JWE, JWK框架的java实现。
参考git地址

引入

Maven

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

Gradle:

dependencies {compile 'io.jsonwebtoken:jjwt:0.9.0'
}

使用方法

生成token

getJwtToken是生成jjwt里的token方法。


import com.sun.javafx.scene.traversal.Algorithm;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultJwsHeader;import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;private String  SECRET = "DyoonSecret_0581";
private void getJwtToken(){Date iatDate = new Date();// expire timeCalendar nowTime = Calendar.getInstance();//有10天有效期nowTime.add(Calendar.DATE, 10);Date expiresDate = nowTime.getTime();Claims claims = Jwts.claims();claims.put("name","cy");claims.put("userId", "222");claims.setAudience("cy");claims.setIssuer("cy");String token = Jwts.builder().setClaims(claims).setExpiration(expiresDate).signWith(SignatureAlgorithm.HS512, SECRET).compact();}

上面将token中的载荷放在chaims中,其实chaims是JWT内部维持的一个存放有效信息的地方,不论使用任何API,最终都使用chaims保存信息。
setClaims有2个重载

  • JwtBuilder setClaims(Claims claims);
  • JwtBuilder setClaims(Map<String, Object> claims);
    不能就是说,我们也可以直接传入map值对象。

解析token

parseJwtToken方法是解析token。

public void parseJwtToken(String token) {try{}catch (Exception e){}Jws<Claims> jws = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);String signature = jws.getSignature();Map<String, String> header = jws.getHeader();Claims Claims = jws.getBody();}

扩展阅读
讲真,别再使用JWT了!

JWT全面解读、使用步骤相关推荐

  1. 【导航业务框架】开源无人驾驶项目autoware解读

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 一.Autoware的整体框架和模块 1.Autoware介绍 2. ...

  2. ASP.NET Core 3.1 系列之 Web API 添加身份验证Jwt

    ASP.NET Core 3.1 系列之 Web API 中间件篇 (一) 身份验证(Jwt)中间件使用步骤 添加 NuGet程序包 添加包:Microsoft.AspNetCore.Authenti ...

  3. 小程序 jwt_使用JWT保护应用程序安全的简介

    小程序 jwt JSON Web Tokens have become the favorite choice among modern developers when implementing us ...

  4. 跟我学Springboot开发后端管理系统8:Matrxi-Web权限设计实现

    上篇文章讲述了Matrix-web整体实现的权限控制的思路.现在来回顾一下: 首先,用户需要登录,填用户名.密码,后端接收到登录请求,进行用户.密码的校验,校验成功后则根据用户名生成Token,并返回 ...

  5. https证书互信解决方案—创建私有CA并申请证书

    前言 https相较于http而言有很大的安全性,当我们一个服务开启https并与之通信时,往往需要证书的认证,如果是浏览器访问服务,只要在浏览器内设置信任证书即可,而如果是程序内访问服务(如java ...

  6. 老李分享:HTTP协议之协议头

    老李分享:HTTP协议之协议头 当我们打开一个网页时,浏览器要向网站服务器发送一个HTTP请求头,然后网站服务器根据HTTP请求头的内容生成当次请求的内容发送给浏览器.你明白HTTP请求头的具体含意吗 ...

  7. 因果推断笔记——因果图建模之微软开源的EconML(五)

    文章目录 1 EconML介绍 1.1 EconML介绍 1.2 一些理论解答 1.3 常规CATE的估计器 1.4 IV工具变量 + CATE的估计器 1.5 动态处理效应的估计器 2 智能营销案例 ...

  8. apple授权登录(服务端)

    一.apple配置 1.注册开发者 在apple开发者官网( https://developer.apple.com/)注册成开发者 2.创建应用 点击左边菜单的Certificates, Ident ...

  9. 【Excel】绘图案例_常见复合图:簇状图+堆积图+折线图

    [Excel]绘图案例_常见复合图:簇状图+堆积图+折线图 前言 最近有朋友让我帮忙用excel画图,老实说我很讨厌用excel画图,点来点去,复杂一些还不能复用,非常繁琐.当然,入门也很简单.需求时 ...

  10. Docker最新超详细教程——基本操作

    Docker最新超详细教程--基本操作 一.镜像操作 镜像名称 镜像命令 案例一:拉取.查看镜像 案例二:保存.导入镜像 二.容器操作 容器相关命令 容器三个状态 暂停与停止有什么差别? 案例一:创建 ...

最新文章

  1. 第三次冲刺阶段第五天
  2. OVS 各功能调用过程(三十一)
  3. Spring Cloud 微服务实战系列-Ribbon入门RestTemplate 介绍
  4. 信息论与编码_庆祝中山大学计算机科学系成立40周年系列活动 | 第四届“信息论与编码中大论坛”...
  5. C#:泛型(Generic)
  6. deeplearning4j的学习
  7. 需求分析之软件界面设计
  8. python Word批量转PDF
  9. layui iframe弹出层高度自适应,并垂直居中
  10. java 0-999 阿拉伯数字转英文
  11. 请求的操作需要提升 windows7 route add命令 windows7添加路由
  12. 【Python 实战基础】Pandas如何从股票数据找出收盘价最低行
  13. ddl是什么意思网络语_大学赶ddl是什么意思?DDL语句有什么功能?
  14. java sapi_使用Microsoft SAPI进行语音合成
  15. mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such f
  16. Celery Django 运行 task 任务的时候 提示NotRegistered
  17. 201671010434 王雯涵《英文文本统计分析》结对项目报告
  18. 计算机中的英语六级作文万能模板,英语六级作文万能模板(4篇)
  19. Paper pusher 摆弄文件的人
  20. 软路由的正确组网姿势(上篇)

热门文章

  1. 【知识点总结】电路原理 第一讲
  2. CSS度量单位px/pt/em/in/pc/mm/cm
  3. 不忘来时路 心系梦归处
  4. 读《富爸爸,穷爸爸》后感(二)
  5. 计算机win7的后缀名怎么显示,win7显示文件后缀名怎么显示?win7显示文件后缀
  6. Android 9.0 开启飞行模式
  7. linux 恢复member1账户,Linux操作系统第9讲 帐户管理和权限管理.ppt
  8. vant-list上拉加载onload事件触发多次
  9. 树的遍历 ALDS1_7_C: Tree Walk
  10. html 中全角波浪线,中间波浪怎么打出来,靠上的波浪符号怎么打