JWT简单介绍

JWT简单介绍


视频地址,讲的不清楚的地方可以at我:
https://v.qq.com/x/page/m0682jz4yzh.html

1.背景介绍

什么是JWT

JWT(JSON WEB
TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串

  • 标准定义方为ISOC(Internet Society 国际互联网协会),标准文件为 RFC
    7519,目前绝大多数的网络标准都是由ISOC定义的。
  • RFC(Request For
    Comments),意即“请求评议”,包含了关于Internet的几乎所有重要的文字资料和标准,也称为“网络知识圣经”

JWT用来做什么?怎么来的?

由于http协议是无状态的,所以客户端每次访问都是新的请求。这样每次请求都需要验证身份,传统方式是用session+cookie来记录/传输用户信息,而JWT就是更安全方便的方式。它的特点就是简洁,紧凑和自包含,而且不占空间,传输速度快,而且有利于多端分离,接口的交互等等
JWT是一种Token规范,主要面向的还是登录、验证和授权方向,当然也可以用只来传递信息。一般都是存在header里,也可以存在cookie里。

  • 紧凑: 意味着这个字符串很小,甚至可以通过URL参数,POSTparameter中以Http Header的方式传输。

  • 自包含:传输的字符串包含很多信息,别人拿到以后就不需要再多次访问数据库获取信息,而且通过其中的信息就可以知道加密类型和方式,当然解密需要公钥和密钥。

应用场景:认证和授权,认证解决[你是谁]的问题,授权解决了[你能做什么]的问题 一次性验证,邮件验证
注册激活
登录验证,长期未登录激活
应用授权
单点登录

什么是TOKEN
Token是服务器签发的一串加密字符串,是为了给客户端重复访问的一个令牌,作用是为了证明请求者(客户端)的身份,保持用户长期保持登录状态。

JWT和TOKEN的关系
JWT就是TOKEN的一种载体,或者说JWT是一种标准,而Token是一个概念,而JWT就是这个概念执行的一种规范,通俗点说token就是一串字符串,jwt就是加上类型,信息等数据再加密包装一下成为一个新的token。
最直观的区别就是不使用JWT的token需要查询数据库来验证,而使用JWT可以不用对数据库进行操作,因为它本身包含了可自定义的信息

  • JWT是所有语言通用的
  • 其实sessionID储存也算是一种token

2.知识剖析

JWT的数据结构以及签发的过程
JWT由三部分构成:header(头部)、payload(载荷)和signature(签名)。

Header 头部信息:指定类型和算法
Payload 荷载信息:存放Claims声明信息
Signature 签名:把前两者对应的Json结构进行base64url编码之后的字符串拼接起来和密钥放一起加密后的签名
组成方式为 header.payload.signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiLlvKDlvLoiLCJuYW1lIjoiNzg5IiwiZXhwIjoxNTI4MzY0MjU5LCJpYXQiOjE1MjgzNjMwNTl9.574koY-c9SqMNNzfvAWQuKEnimWeZAcoFQ5XudNWF3o

Header的结构
* type 声明类型
* algorithm 声明加密算法
格式: {“typ”: “JWT”,“alg”: “HS256”}

payload的结构
* 声明信息
payload用来承载要传递的数据,它的json结构实际上是对JWT要传递的数据的声明,这些声明被JWT标准称为claims(声明),它的每个属性键值对其实就是一个claim,JWT常用的有两种声明,一种是Reserved claims(保留声明),也就是JWT规定的标准声明。
一种是Private claims(自定义声明),我们在这里定义要传递的信息
还有一种是public claims(公共声明),这个目前没用到。

			格式: {"name": "value","id": "value2"}

标准声明(JWT保留声明)
•iss(Issuser):代表这个JWT的签发主体;
•sub(Subject):代表这个JWT的主体,即它的所有人;
•aud(Audience):代表这个JWT的接收对象;
•exp(Expiration time):是一个时间戳,代表这个JWT的过期时间;
•nbf(Not Before):是一个时间戳,代表这个JWT生效的开始时间,意味着在这个时间之前验证JWT是会失败的;
•iat(Issued at):是一个时间戳,代表这个JWT的签发时间;
•jti(JWT ID):是JWT的唯一标识。

signature
* 签名
把header和payload对应的json结构进行base64url编码之后得到的字符串用点号拼接起来,然后根据header里面alg指定的签名算法生成出来的,然后添加自己设定的key进行加密签名
添加:
.sign(Algorithm.HMAC256(Key))
在线加密解密:http://tool.oschina.net/encrypt?type=3

工具
auth0     OAuth2.0     JWTUtil     jsonwebtoken

3.常见问题

如何验证

当接收方接收到一个JWT的时候,首先要对这个JWT的完整性进行验证,这个就是签名认证。它验证的方法其实很简单,只要把header使用base64url解码以后就知道签发者用什么算法做的签名,然后用这个算法对header和payload加密一下,再比较这个签名是否和JWT本身包含的signature是否完全相同,只要不同就可以认为这个JWT是被篡改过的。所以接收方生成签名的时候必须使用跟JWT发送方相同的密钥。
再次就是验证payload里的部分,比如是否过期,还有自定义的信息是否相同,加上已经前面验证的signature,这样就保证了这个签名的有效性

互斥登录/修改密码后登录的问题
场景:用户在多个设备或者其它浏览器/IP登录以后或者修改密码以后,那其它的设备就需要自动退出登录

  • 用户修改密码之后签发一个新的token来覆盖之前的。但是之前的token只要在失效之前仍然是可以验证并且登录的
  • 用户手动退出的时候也是需要token失效的,这就需要退出的时候直接清除或者覆盖客户端保存的token。同上,之前的token仍然有效,所以token的时间不能太长
  • 设置黑名单,在签发新token的时候把之前未过期的token加入黑名单使之失效。但是这样就需要储存token,而jwt的优点就是不需要储存空间。

续签
场景:需要用户长期登录的应用,比如用你开发需要用户保持登录的应用,在使用token的时候保证用户体验不需要频繁登录操作,又要保证用户在一段时间之后登录过期重新登录,主要是一个用户体验和用户信息安全的问题。这个时候又要求token不能过长,只能通过续签来保持登录状态
又或者说用户登录的时候你需要获取用户在社交网站的信息,就需要获取社交网站授权的token,这也需要续签,不过这是向社交网站续签。这里后面说。

何时续签:
1.每次请求刷新 每次请求直接覆盖签发新的token
2.记录时间定时刷新 设置一个定时器,记录签发时间,然后到过期的时候签发新的
3.临期时刷新 访问的时候对比时间,如果即将过期就立即刷新。
4.过期后续签,这样设置过期时间的意义就在于如果token被盗取后黑客登录也需要续签,这样用户再次登录客户端就会发现用户登录异常。而且每次获取的token都是新的,旧的只能获取一次续签的机会,也就说如果用户续签以后之前的token就不能再续签了。
5.jwt-autorefresh(JWT自动刷新)(有限制条件,在客户端定时刷新)

4.编码实战

5.扩展思考

			如何维持 token 长期动态更新?	
			一是在用户登录后生成一个有效期很长的Token(比如一个月乃至半年),保存在服务器端,同时发给客户端, 客户端的每次请求就以这个Token验证身份.	
			安全性非常低,而且还会占用内存,更容易被获取信息,即使使用https传输也能在客户端本地被获取信息,长时间冒充用户登录。
			
		
			二是在第一次用账号密码登录的时候服务器返回两个过期时间不同的 token
			一个短时效的token( Access Token )
		一个长时效的token(Refresh Token)
		Access Token过期之后,验证Refresh token 如果通过验证就重新获取一个Access token,如果两者都过期,就需要重新登录。这种方式一般用来做授权,是微信等平台的设计方案,用的是oauth2实现。因为用户使用qq、微信等登录第三方的时候就需要授权,这个授权有一个长期的一个短期的,这样就不需要用户每次都授权,只要短期授权过期,且长期授权未过期的情况下第三方就可以继续获得授权。如果长期授权也过期了那么就需要用户重新授权登录了
		
					
			三是以旧换新
			只使用一个短期的token,每次请求用这个token认证,过期了就凭此认证换取一个新的,也只能换取一次,这也是前面说的过期续签。当用户不登录的情况下被盗取token,黑客如果持续登录就需要持续更换旧的token,但是这时候如果用户登录的话服务器就会发现用户频繁更换ip和客户端登录的异常,这样可以强制让用户重新登录。但是如果用户长期不登也就没办法判断是否被盗取信息,这也是需要解决的地方。毕竟安全性都是在一定条件下才算安全的。
		
					
			
			而你作为第三方的时候,写了一个应用,要得到访问用户在某些大站的一些资源的授权,用户那里会弹出来大站的授权页面,这要求用户输入帐号密码做验证的。 然后你拿到 access token 和 refresh token 以后,快过期了用 refresh token 刷一下,就省去让用户再输入帐号密码登录然后再授权的这一步了。
		
					
		单点登录
		oauth2.0
		单点登录是多系统下应用的,比如一个公司有OA系统,门户系统,管理系统,商品系统等等,公司用户可以在内部使用账户统一登录,不用每天登录每个系统浪费时间。(qq微信登录其它网站也算是单点登录,但是它们是跨域的,这样不推荐使用jwt)。这个有很多办法解决,比如浏览器记录用户名密码,使用session等等,这里也是可以使用token验证的,只是需要使用Oauth2,它不向下兼容。

6.参考文献
JWT实现token-based会话管理 : https://www.cnblogs.com/lyzg/p/6028341.html
RFC 7519 : https://tools.ietf.org/html/rfc7519
RFC : https://baike.baidu.com/item/RFC/1840?fr=aladdin
auth0:https://auth0.com/docs/tokens/refresh-token/current
oauth2 : https://oauth.net/2/

7.更多讨论

A:JWT有什么不好的地方?
Q:不好的地方就是JWT等于说是泼出去的水,发出去的令牌,不可更改,只要有效期内就可以永使用
A: JWT安全性如何?
Q: 这也是JWT最重要的一点,它的出现就是为了免登陆或者权限控制,所以它的安全性至关重要。所以它虽然是一直加密的,但是安全性总是建立在相对性之上的。所以只能说一定程度上是安全的。
A: JWT如何存放?
Q: JWT不需要存放,或者说存放在客户端那里。服务端只需要有解密算法就可以判断当前的JWT是不是有效的。

<think>嗯,用户之前问过Java毕业设计涉及的技术,现在接着问JWT的详细介绍。我需要先理解JWT是什么,以及它在Java项目中的应用场景。用户可能是在做毕业设计时遇到了身份验证的问题,或者想了解如何安全地管理用户会话。 JWT的全称是JSON Web Token,应该先解释它的基本概念,结构组成,比如header、payload、signature。然后要说明它的工作原理,用户可能想知道为什么使用JWT而不是传统的session方式,所以需要比较两者的优缺点,比如无状态、跨域支持这些。 用户可能关心JWT的安全性,所以需要提到如何防止被篡改,比如签名机制,以及存储时需要注意的问题,比如不要放在localStorage中,可能涉及XSS和CSRF攻击的防范。另外,JWT的过期时间设置也很重要,避免令牌被长期滥用。 在Java中使用JWT的话,可能需要推荐一些库,比如jjwt,然后给出一个简单的示例代码,说明如何生成和验证Token。这部分需要确保代码正确,并且符合Java的常见实践,比如使用Spring Security整合。 还要考虑用户可能的误区,比如JWT的存储位置,是否需要服务器端保存,以及注销和续签的问题。这些都是实际开发中常见的问题,需要详细解释解决方案,比如黑名单或者使用refresh token机制。 最后,结合之前用户的问题,JWT通常是毕业设计中实现用户认证的一部分,可以联系到之前提到的技术栈,比如Spring Boot、Spring Security,以及Redis用来处理黑名单。这样帮助用户将JWT整合到他们的项目架构中,确保他们理解如何在实际项目中应用。</think>以下是对JWT的详细介绍,从原理到应用全面解析: --- ### 一、JWT基础概念 **JWT(JSON Web Token)** 是一种开放标准(RFC 7519),用于在各方之间安全传输JSON格式的信息。主要应用场景: - 身份验证(最常见的用途) - 安全信息交换 - 无状态API授权 ### 二、JWT结构解析 一个标准JWT由三部分组成,格式为: $$ \text{Header.Payload.Signature} $$ 例如: ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ``` #### 1. Header(头部) - 声明令牌类型和签名算法 - Base64Url编码后的JSON ```json { "alg": "HS256", // 签名算法(如HS256/RSA) "typ": "JWT" // 令牌类型 } ``` #### 2. Payload(载荷) - 包含声明(claims)的JSON对象 - 标准声明(建议但不强制使用): ```json { "sub": "1234567890", // 主题(用户ID) "name": "John Doe", // 自定义声明 "iat": 1516239022, // 签发时间(时间戳) "exp": 1516239122 // 过期时间 } ``` - **三类声明**: - Registered claims:预定义标准字段(如iss, exp, sub等) - Public claims:公开定义的字段 - Private claims:双方协商的自定义字段 #### 3. Signature(签名) - 防止数据篡改的核心安全机制 - 计算公式: $$ \text{签名} = \text{HMAC\_SHA256}( \text{base64UrlEncode(header)} + "." + \text{base64UrlEncode(payload)}, \text{secretKey} ) $$ ### 三、JWT工作流程 ```mermaid sequenceDiagram 用户->>客户端: 提交登录凭证 客户端->>服务器: 发送用户名/密码 服务器->>服务器: 验证凭证有效性 服务器->>客户端: 返回签名的JWT 客户端->>服务器: 后续请求携带JWT(Header中) 服务器->>服务器: 验证签名+检查过期时间 服务器->>客户端: 返回请求数据 ``` ### 四、JWT核心特性 #### 优点: 1. **无状态**:服务端无需存储会话信息 2. **跨域支持**:适合微服务和分布式系统 3. **自包含**:payload可携带用户基本信息 4. **防篡改**:签名机制保证数据完整性 #### 缺点: 1. **无法废止**:签发后有效期内始终有效(需配合黑名单机制) 2. **payload不宜过大**:增加网络传输负担 3. **密钥管理**:密钥泄露会导致系统安全崩溃 ### 五、Java中的JWT实现 #### 常用库: - **jjwt**(Java JWT):最流行的实现 - **auth0/java-jwt**:功能全面的开源库 - **Nimbus JOSE+JWT**:符合JOSE规范 #### Spring Boot整合示例(使用jjwt): ```java // 生成Token public String createToken(String username) { return Jwts.builder() .setSubject(username) .setExpiration(new Date(System.currentTimeMillis() + 3600_000)) // 1小时 .signWith(SignatureAlgorithm.HS512, "yourSecretKey") .compact(); } // 验证Token public Claims parseToken(String token) { return Jwts.parser() .setSigningKey("yourSecretKey") .parseClaimsJws(token) .getBody(); } ``` ### 六、安全实践建议 1. **密钥管理**: - 使用至少256位的强密钥 - 密钥存储在环境变量/配置中心,避免硬编码 2. **传输安全**: - 必须通过HTTPS传输 - 建议存放在HttpOnly Cookie中(防XSS攻击) 3. **时效控制**: - 设置合理过期时间(通常15分钟-2小时) - 使用refresh token机制续期 4. **敏感数据**: - 不要在payload中存储密码等敏感信息 - 避免暴露用户隐私数据 ### 七、JWT vs Session 对比 | 特性 | JWT | Session | |---------------------|------------------------------|-----------------------| | 存储位置 | 客户端 | 服务端 | | 扩展性 | 天然支持分布式系统 | 需要会话共享方案 | | 安全性 | 依赖签名算法和密钥管理 | 依赖Cookie安全配置 | | 性能影响 | 需解析签名(计算开销) | 需查询会话存储 | | 失效机制 | 需结合黑名单或短过期时间 | 直接删除会话即可 | ### 八、常见问题解决方案 1. **注销问题**: - 方案1:使用Token黑名单(Redis存储失效Token) - 方案2:设置较短过期时间 + 使用refresh token 2. **密钥轮换**: - 定期更新签名密钥 - 新旧密钥并存过渡期 3. **跨域共享**: - 配置CORS策略 - 确保Domain属性正确设置 --- **实际应用建议**:在毕业设计中,推荐将JWT与Spring Security结合使用,配合Redis实现黑名单管理。典型流程可参考: $$ \text{用户登录} \rightarrow \text{签发JWT} \rightarrow \text{API鉴权} \rightarrow \text{权限控制} $$ 注意控制Payload体积,建议只存储用户ID和必要角色信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值