前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JWT令牌相关面试试题(举例说明)

JWT令牌相关面试试题(举例说明)

原创
作者头像
changwoo
发布2024-06-23 22:05:00
910
发布2024-06-23 22:05:00

什么是JWT令牌

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间以json数据格式安全的传输信息。

JWT令牌的结构

JWT令牌由三个部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature),它们之间使用点(.)分隔。

一个JWT令牌的典型结构如下:

代码语言:javascript
复制
xxxxx.yyyyy.zzzzz

Header(头部): 头部通常由两部分组成:令牌类型(即 "JWT")和所使用的签名算法(如HMAC SHA256或RSA)。头部是一个JSON对象,使用Base64Url编码。

代码语言:javascript
复制
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload(载荷): 携带一些自定义信息、默认信息等。载荷部分包含声明(claims),声明是关于实体(通常是用户)和其他数据的声明。有三种类型的声明:注册声明(registered claims)、公共声明(public claims)和私有声明(private claims)。这个部分也是一个JSON对象,使用Base64Url编码。

代码语言:javascript
复制
{
  "id": "1",
  "name": "John",
  "exp": 1516239022
}

Signature(签名): 签名部分是为了确保令牌不被篡改。它由编码后的头部、编码后的载荷和一个密钥通过指定签名算法计算而来

正是因为jwt令牌数字签名部分的存在,所以整个jwt 令牌是非常安全可靠的。一旦jwt令牌当中任何一个部分、任何一个字符被篡改了,整个令牌在校验的时候都会失败,所以它是非常安全可靠的。

JWT令牌签名的创建过程

假如采用HMAC SHA256算法,签名的完整创建过程如下所示:

代码语言:javascript
复制
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

假设Header为:

代码语言:javascript
复制
{
  "alg": "HS256",
  "typ": "JWT"
}

编码后的Header为:

代码语言:javascript
复制
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

假设Payload为:

代码语言:javascript
复制
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

编码后的Payload为:

代码语言:javascript
复制
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

生成签名:

代码语言:javascript
复制
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

假设secret为:your-256-bit-secret

生成的签名(Base64Url):

代码语言:javascript
复制
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

完整的 JWT:

代码语言:javascript
复制
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT令牌是为了解决什么问题

传统会话跟踪技术(同一次会话中多次请求之间的数据可以共享)是通过cookie和session,但这两者有许多缺点。

以用户验证这一实际场景举例,如果使用JWT令牌进行用户验证,服务器在用户成功登录后生成一个JWT令牌,并将其发送给客户端浏览器。客户端在后续的每个请求中都携带这个令牌,服务器通过验证这个令牌是否存在、令牌是否合法这两个方式来确认用户身份。JWT令牌的优点:

  • 支持PC端、移动端
  • 解决集群环境下的认证问题
  • 减轻服务器的存储压力(无需在服务器端存储)

JWT令牌的优缺点

  • 优点:
    • 支持PC端、移动端
    • 解决集群环境下的认证问题
    • 减轻服务器的存储压力(无需在服务器端存储)
  • 缺点:需要自己实现(包括令牌的生成、令牌的传递、令牌的校验)

JWT令牌能否多服务器共享

因为JWT是无状态的,包含所有必要的信息,并且可以通过签名来验证其完整性,所以不同服务器只需知道签名密钥即可验证令牌、共享数据,而不需要共享会话状态,从而实现了多服务器的之间的共享

JWT令牌多服务器共享的场景举例:

假设有一个负载均衡的应用,分布在多个服务器上,用于处理用户的请求。系统架构主要包含以下三个部分:

  • 服务器1:用于处理用户登录请求,生成JWT令牌。
  • 服务器2:用于处理用户的其他请求,验证JWT令牌。
  • 负载均衡器:分配用户的请求到不同的服务器。

步骤1:用户通过HTTP POST请求,用于发送用户的登录信息到服务器,以进行身份验证。负载均衡器将请求分配到服务器1。

代码语言:javascript
复制
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json
​
{
  "username": "user1",
  "password": "password123"
}

步骤2:服务器1验证用户凭证,如果有效,则生成一个JWT令牌,包含用户ID和其他信息,并使用服务器的签名密钥进行签名。以下代码声明令牌的主题为user1,令牌有效期为1个小时,使用HS512(HMAC SHA-512)算法和密钥“shared-secret-key”对JWT进行签名。

代码语言:javascript
复制
String jwtToken = Jwts.builder()
                      .setSubject("user1")
                      .setExpiration(new Date(System.currentTimeMillis() + 3600000))
                      .signWith(SignatureAlgorithm.HS512, "shared-secret-key")
                      .compact();

步骤3:服务器1将JWT令牌的字符串形式token返回给客户端,客户端将这个令牌存储在本地存储或Cookie中。唠叨:客户端在后续的每次请求中,都需要在请求头header中将这个令牌携带到服务端,请求头的名称为 token ,值为登录时下发的JWT令牌,验证通过后才能放行处理请求。

代码语言:javascript
复制
​
​
HTTP/1.1 200 OK
Content-Type: application/json
​
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

步骤4:客户端请求一个受保护的资源,负载均衡器将请求分配到服务器2。服务器2接收到请求后,从HTTP请求头部提取名为token的JWT令牌,并使用共享的签名密钥"shared-secret-key"验证令牌。如果令牌签名验证成功且未过期,则处理请求并返回响应。

代码语言:javascript
复制
// 验证JWT令牌
Claims claims = Jwts.parser()
                    .setSigningKey("shared-secret-key")
                    .parseClaimsJws(eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...)
                    .getBody();
​
String username = claims.getSubject();

步骤5:服务器2验证令牌成功后,处理请求并返回响应。

代码语言:javascript
复制
HTTP/1.1 200 OK
Content-Type: application/json
​
{
  "message": "This is a protected resource."
}

Session和JWT有什么区别

1.数据存储方式

Session:

  • 服务器端存储:会话数据存储在服务器端(例如内存、数据库或其他持久化存储)。服务器需要维护每个用户的会话状态。
  • 客户端存储:客户端仅存储一个会话ID,通常保存在Cookie中,后续请求会携带此会话ID来查找服务器端存储的会话数据。

JWT:

  • 客户端存储:JWT令牌自包含所有会话数据,存储在客户端本地(或cookie)。服务器无需存储会话状态,只需共享签名密钥即可验证JWT令牌。
  • 无服务器存储:服务器不需要存储或管理会话数据,令牌中包含所有必要的信息(如用户身份和权限)。

2.扩展性

Session:

  • 扩展性差:在分布式系统中,需要共享会话数据或使用集中式存储(如数据库或缓存服务器),增加了复杂性和性能瓶颈。
  • 服务器负担重:随着用户数量增加,服务器需要管理更多的会话数据,可能会导致性能下降。

JWT:

  • 扩展性好:由于JWT令牌是无状态的,服务器不需要存储会话数据,易于在分布式系统和微服务架构中扩展。
  • 减少服务器负担:每个请求携带完整的JWT令牌,服务器只需验证令牌的签名和有效期,不需查找会话数据,提升了性能。

3.安全性

Session:

  • 安全性高:会话数据存储在服务器端,不易被篡改。客户端只存储一个会话ID,攻击者难以伪造会话。
  • 可控性强:服务器可以随时终止会话或修改会话数据,具有更高的控制权。例如,可以立即使某个会话失效。

JWT:

  • 安全性问题:JWT令牌一旦泄露,攻击者可以伪装用户,直到令牌过期。
  • 可控性弱:服务器一旦签发JWT令牌,在其有效期内无法修改或撤销,除非使用复杂的黑名单机制来使令牌失效。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是JWT令牌
  • JWT令牌的结构
  • JWT令牌签名的创建过程
  • JWT令牌是为了解决什么问题
  • JWT令牌的优缺点
  • JWT令牌能否多服务器共享
  • Session和JWT有什么区别
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档