什么是JWT?新手5分钟入门JWT的使用
1 什么是JWT
JSON Web Token(JWT)是一种开放标准(RFC7519),它定义了一种紧凑而独立的方式,用于在各方之间作为JSON对象安全地传输信息。此信息是可以验证和信任的,因为它是经过数字签名的。
来源JWT官网(https://jwt.io/introduction)
通俗的来说,jwt就是应用认证的一种解决方案,在讨论jwt之前,需要先了解的传统的session认证和token认证区别。
1.1 传统的session认证步骤:
- 客户端向服务端发送账号密码进行认证。
- 服务端在校验账号密码正确之后,将当前用户的基本信息保存到当前会话(session)中,并将sessionid返回给客户端。
- 客户端在拿到sessionid之后将其保存到cookie中,并在以后的每次请求中都携带该sessionid。
- 服务端根据客户端传过来的sessionid对当前用户进行认证,判断是否合法。
1.1.1 session认证存在的问题:
- 所有的session都在服务端进行保存,当用户量不断增大的时候服务器的开销也会随之增大。
- 在一个应用的服务器有多台的情况下,针对一个用户,就必须在每台服务器上都维护一个相同的session,或者引入Redis等中间件对session进行统一的管理。
1.2 token认证步骤:
- 客户端向服务端发送账号密码进行认证。
- 服务端在校验账号密码正确之后,生成token字符串返回给客户端。
- 客户端收到token之后进行保存,并在之后的每一次请求中将该token放到请求头中一并发送。
- 服务端在收到客户端传递的token之后,对token进行验证,判断是否合法。
- 使用token进行认证的话,服务端不需要保存任何会话信息或者用户信息,所有的信息都分散保存在客户端中,客户端每次请求的时候自己带上token即可。
2 JWT的构成
jwt是一个很长的字符串,中间用“.”分割成三部分,实际的jwt如下所示:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsZWUiLCJpc3MiOiJsZWUiLCJpZCI6IjEyMzQ1NiIsInVzZXJOYW1lIjoiYWRtaW4iLCJleHAiOjE2MzQwMTU2MTgsImlhdCI6MTYzNDAwODQxOCwianRpIjoiZTY4ODAwNzUtODA5Mi00ZTM0LWEzZDctYmQ1YmQ4ZTA0YjBkIn0.MOPUmnWzbFijlM_vGESF6YdBDvSW3QtIh1qS8i_yuPc
jwt的三个部分如下:
- Header(头部)
- Payload(负载)
- Signature(签名)
2.1 Header
Header部分是一个json字符串,保存的是jwt的元数据,格式如下:
{"alg": "HS256","typ": "JWT"
}
- alg:签名的加密方式
- typ:表示这个令牌(token)的类型(type),JWT令牌统一写为JWT
最后将Header的json字符串进行Base64编码之后就得到了jwt的第一部分
2.2 Payload
Payload部分同样是一个json字符串,其中保存的是有效信息,这些信息主要包含三个部分:
- 标准中注册的声明
- 公共的声明
- 私有的声明
2.2.1 标准中注册的声明(JWT官方规定的字段):
- iss:jwt签发者
- sub:jwt所面向的用户
- aud:接收jwt的一方
- exp:jwt的过期时间,这个过期时间必须要大于签发时间
- nbf:定义在什么时间之前,该jwt都是不可用的
- iat:jwt的签发时间
- jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
2.2.2 公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。
2.2.3 私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
Payload示例:
{"sub":"lee","iss":"lee","id":"123456","exp":"1634015618","iat":"1634008418","jti":"e6880075-8092-4e34-a3d7-bd5bd8e04b0d","userName":"admin"
}
最后将Payload的json字符串进行Base64编码之后就得到了jwt的第二部分
2.3 Signature
jwt的第三部分就是签名部分,针对以下三个部分进行加密即可:
- Header(Base64编码后的)
- Payload(Base64编码后的)
- secret
将Base64编码后的Header和Payload用“.”进行连接,然后使用Header中的加密算法进行加盐secret加密。
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
最后加密出的字符串就是jwt的第三部分。
3 JWT的使用
当客户端接收到服务端发来的jwt字符串之后,将其保存到Cookie或者localStorage里面,然后每次向服务器发送请求的时候都带上JWT,将jwt放到HTTP请求的头信息Authorization中。
Authorization: Bearer <token>
3.1 服务端验证步骤
- 当服务端接收到客户端的token字符串之后,首先对字符串的第一部分进行解码,得到Header。
- 取出Header中的加密方式,使用该加密方式和secret对字符串的第一部分和第二部分进行加密,如果得到的签名和传递过来的签名一致,则认为该token合法。
- 对第二部分进行解码,得到需要的数据。
3.2 代码
使用jjwt实现jwt的签发和解析获取payload中的数据
- 引入
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version>
</dependency>
- Java代码
package com.jwt;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;public class JwtDemo {//私钥 生成签名的时候使用的秘钥secret,一般可以从本地配置文件中读取private final static String secret = "123456789";/*** 创建jwt*/public static String createJwtToken(){// HeaderMap<String, Object> map = new HashMap<>();map.put("alg", "HS256");map.put("typ", "JWT");//PayloadMap<String,Object> claims = new HashMap<String,Object>();//自定义数据,根据业务需要添加claims.put("id","123456");claims.put("userName", "admin");//标准中注册的声明claims.put("iss", "lee");//生成jwtreturn Jwts.builder().setHeader(map) // 添加Header信息.setClaims(claims) // 添加Payload信息.setId(UUID.randomUUID().toString()) // 设置jti:是JWT的唯一标识.setIssuedAt(new Date()) // 设置iat: jwt的签发时间.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 设置exp:jwt过期时间,3600秒=1小时.setSubject("Jack") //设置sub:代表这个jwt所面向的用户.signWith(SignatureAlgorithm.HS256, secret)//设置签名:通过签名算法和秘钥生成签名.compact();}/*** 从jwt中获取 Payload 信息*/private static Claims getClaimsFromJwt(String jwt) {Claims claims = null;try {claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt).getBody();} catch (Exception e) {e.printStackTrace();}return claims;}public static void main(String[] args) {String jwtToken = createJwtToken();System.out.println("JWT Token: "+ jwtToken);System.out.println("=======================================================");Claims claims = getClaimsFromJwt(jwtToken);System.out.println("claims: " + claims);}
}
运行结果
JWT Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKYWNrIiwiaXNzIjoibGVlIiwiaWQiOiIxMjM0NTYiLCJ1c2VyTmFtZSI6ImFkbWluIiwiZXhwIjoxNjM0MDMzMjEwLCJpYXQiOjE2MzQwMjYwMTAsImp0aSI6ImQ4ZDk3ZjMzLTIwMTctNGQzMi04ZDRlLWM0Yzc3ZjU2NDUzMyJ9.N9SRwmwmFEFGU5hgRsQqJSngmasvTGZ5WXi1t5JO3MI
=======================================================
claims: {sub=Jack, iss=lee, id=123456, userName=admin, exp=1634033210, iat=1634026010, jti=d8d97f33-2017-4d32-8d4e-c4c77f564533}
3.3 建议
- Payload中不要存放敏感信息。
- 保存好secret私钥,不要泄露。
- jwt的有效期需要根据应用来决定,时间不宜设置过长。
- 如果可以,请使用HTTPS。
什么是JWT?新手5分钟入门JWT的使用相关推荐
- JWT ( JSON Web Token ) 入门教程
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 一.跨域认证的问题 互联网服务离不开用户认证.一般流程是下面这样. 1.用户向服务器发送用户名和密码 ...
- 身份认证——session认证机制与JWT认证机制(入门到使用)
首先我们要了解什么是身份认证(Authentication)? 身份认证也叫身份验证或者鉴权,指通过一定的手段来完成对用户身份的验证 我们会使用session和JWT认证机制进行开发,那么我们在什么情 ...
- python怎么样才算入门编程-新手如何快速入门Python编程?听过来人说经验!
新手如何快速入门Python编程?站在别人的肩膀上总是要快些的,如果你不借鉴前人的经验,那么前人踩过的坑你也会踩,所以来看看吧: Python是一种编程语言,可以用来做网站.写自动化测试脚本.做数据分 ...
- STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结
摘自:STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结 作者:自信且爱笑' 发布时间: 2021-04-28 21:17:40 网址:https://blog. ...
- linux pandas教程_十分钟入门 Pandas
# 十分钟入门 Pandas 本节是帮助 Pandas 新手快速上手的简介.烹饪指南里介绍了更多实用案例. 本节以下列方式导入 Pandas 与 NumPy: In [1]: import numpy ...
- 新手如何快速入门Python(菜鸟必看篇)
学习任何一门语言都是从入门(1年左右),通过不间断练习达到熟练水准(3到5年),少数人最终能精通语言,成为执牛耳者,他们是金字塔的最顶层.虽然万事开头难,但好的开始是成功的一半,今天这篇文章就来谈谈如 ...
- php jwt是什么,JWT是什么?对JWT的简单认识
本篇文章给大家带来的内容是关于JWT是什么?对JWT的简单认识,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt. ...
- python 三分钟入门_Cython 三分钟入门教程
作者:perrygeo 译者:赖勇浩(http://laiyonghao.com) 原文:http://www.perrygeo.net/wordpress/?p=116 我最喜欢的是Python,它 ...
- 技术19期:1分钟入门数据治理!必看!【技术篇】
1分钟入门数据治理!必看![技术篇] 前言: 在进行大数据开发过程中,数据调研和开发规范都是必不可少的.数据调研便于理清数据源之间的关系,梳理出哪些数据是符合当下的业务场景以及确定所要用到的加工口径等 ...
最新文章
- 和 杠精 聊Redis多线程 :(
- phantomjsjava_Java利用Phantomjs实现生成图片的功能
- 图像文字识别(三):Tesseract4.0训练字库,提高正确识别率
- 什么是虚拟化,虚拟化的现状
- python初学者_初学者使用Python的完整介绍
- docker下使用redis
- 错误代码:ERR_UNSAFE_PORT
- 树莓派怎么切换输入法_树莓派如何安装中文输入法
- Win7 您需要Trustedinstaller 提供的权限才能对此文件夹进行更改
- Tech.Ed盛大开幕 梁念坚致开幕辞
- PMP——第4章 项目整合管理
- 2018-08-11 自学笔记
- http状态码-504
- 法规遵从战略:晋升内部IT审计师的策略
- oracle死锁进程杀不掉,oracle杀死死锁进程
- 进击的 JavaScript(四) 之 闭包
- 博途PLC1200/1500PLC用户自定义数据类型(UDT)
- 服务器问题-服务器可以远程登录,本地登录不了
- 电脑垃圾清理专家专业版 9.98 无限试用版与使用测评
- 1分钟让别人喜欢你(三)