You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JWT令牌在登录系统中的工作原理及相关技术疑问

JWT常见疑问解答

嘿,我来帮你逐个拆解这些JWT的疑问,都是实际开发里常碰到的点:

1. 是否需要在JWT令牌中存储用户名和密码?

绝对不要存密码!JWT的payload是明文可解码的(虽然签名能防止篡改,但任何人拿到令牌都能轻松解析出payload内容),把密码放进去等于把敏感信息裸奔给所有人。

用户名可以存,但不是必须——其实更推荐存用户的唯一不可变标识(比如数据库里的user_id),因为用户名可能会被用户修改,而ID是固定的,后续验证身份更可靠。

2. 若需要存储用户信息,应如何存放?比如是否放在payload的sub字段中?

如果要存用户的主体标识,sub字段是JWT标准里推荐的(sub是subject的缩写,专门用来表示令牌的主体,也就是用户),比如:

{
  "sub": "123456",
  "exp": 1735689600,
  "iat": 1694150400
}

如果需要额外存用户名,可以加一个自定义字段,比如"username": "johndoe",但还是那句话,优先用不可变的用户ID。再次强调:密码绝对不能出现在JWT的任何部分,哪怕你觉得加密了也不行,因为payload本身不加密,只是签名验证完整性。

3. 注册时是否需要将令牌存储到数据库?

不需要。JWT的核心优势就是无状态,服务器不需要存储令牌——后续验证的时候,只需要用服务器持有的密钥去验证令牌的签名和过期时间即可。

不过如果需要实现主动失效令牌(比如用户改密码、主动登出),那可能需要维护一个令牌黑名单(比如把失效的令牌ID或者用户ID+过期时间存到Redis这类缓存里),但注册环节完全没必要存储令牌,注册成功后直接生成令牌返回给客户端就行。

4. 相同用户数据生成的JWT令牌是否唯一?

你说得完全对!哪怕用户信息一模一样,生成的JWT也几乎不可能重复。原因有两个:

  • 标准JWT里通常会包含iat(签发时间戳)和exp(过期时间戳)字段,这两个值每次生成令牌都会变化,导致payload内容不同,签名后的结果自然也不同。
  • 很多JWT库还会自动添加jti(JWT唯一标识符)字段,这是一个随机生成的字符串,进一步保证每个令牌的唯一性。

5. 如何用JWT验证用户身份?完整流程是怎样的?

完整的身份验证流程应该是这样的:

  • 登录阶段:
    1. 用户在客户端输入用户名/邮箱和密码,客户端把这些数据发给服务器。
    2. 服务器拿收到的密码,和数据库中存储的用户哈希密码进行比对(注意:数据库里绝对不能存明文密码,必须存哈希后的结果)。
    3. 密码验证通过后,服务器生成JWT:把用户唯一ID(比如user_id)放到payload中,加上过期时间、签发时间等标准字段,然后用服务器的密钥对整个令牌进行签名,生成最终的JWT。
    4. 服务器把JWT返回给客户端,客户端把令牌存在本地(推荐用HttpOnly、Secure的Cookie存储,比localStorage更安全)。
  • 后续请求阶段:
    1. 客户端每次请求需要授权的接口时,把JWT放到请求头的Authorization字段里,格式是Bearer <你的JWT令牌>。
    2. 服务器收到请求后,先提取出令牌,用自己的密钥验证签名是否有效,同时检查令牌是否过期、payload里的用户ID是否在数据库中存在。
    3. 所有验证通过后,服务器就确认请求来自合法用户,然后处理请求并返回结果。

内容的提问来源于stack exchange,提问作者Aniketh Saha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:28:36