API接口安全-1:身份认证之传统Token VS JWT

在Web应用开发中,身份认证是保障系统安全的核心环节。从早期的Session认证到如今的Token机制,技术不断演进以适应分布式、跨域场景的需求。其中,传统TokenJWT(JSON Web Token) 是两种主流方案,但二者在实现原理、适用场景上有显著差异。本文将分析两者的工作机制、优缺点及核心区别。

一、传统Token:依赖存储的"凭证式"认证

1. 什么是传统Token?

传统Token(令牌)是服务器颁发给客户端的"访问凭证",本质是一串随机字符串(如UUID)。客户端通过Token证明自己的身份,服务器通过验证Token的有效性(是否存在、是否过期)决定是否允许访问资源。

2. 工作原理:"存储-校验"的中心化流程

传统Token的认证流程可概括为"生成-存储-验证"三步,核心依赖外部存储(如Redis、数据库)记录Token状态:

认证流程详解
  1. 用户登录 :前端提交账号密码,服务器验证通过后,生成唯一Token(如a1b2c3d4-5678-90ef-ghij-klmnopqrstuv);
  2. 存储Token :服务器将Token作为key,用户ID(或用户信息)作为value,存入Redis(或数据库),并设置过期时间(如2小时);
  3. 客户端存储Token:服务器返回Token给客户端,客户端将其存入Cookie或LocalStorage;
  4. 后续请求验证 :客户端每次请求时,在Header(如Authorization: Bearer <token>)中携带Token;
  5. 服务器校验 :服务器从Redis中查询Token:
    • 若不存在(或已过期):拒绝访问,返回"未登录";
    • 若存在:从value中获取用户ID,查询数据库确认用户信息,验证通过后返回资源。
传统Token流程图解

客户端 服务器 Redis 数据库 登录阶段 1. 登录请求 (账号密码) 2. 生成Token (存储) 3. 存储Token (确认) 4. 返回Token 后续请求阶段 5. 请求+Token (业务接口调用) 6. 查询Token (验证有效性) 7. 验证存在 (返回用户ID) 8. 查询用户信息 (根据用户ID) 9. 返回资源 (业务数据) 客户端 服务器 Redis 数据库

3. 优缺点:分布式友好,但依赖存储

优点
  • 隐藏敏感数据:Token本身是随机字符串,不携带用户信息,避免明文传输风险;
  • 分布式支持:通过Redis等中心化存储,解决Session共享问题,适用于多服务器集群;
  • 灵活可控:可随时在Redis中删除Token(主动吊销),支持强制登出、账号锁定等场景。
缺点
  • 依赖外部存储:每次请求需查询Redis/数据库,增加IO开销,高并发场景可能成为瓶颈;
  • 性能损耗:存储和查询Token的过程会增加服务器响应时间;
  • 架构复杂度:需维护Redis等存储服务,增加系统部署和运维成本。

二、JWT:自包含的"声明式"认证

1. 什么是JWT?

JWT(JSON Web Token)是一种紧凑、自包含的轻量级令牌格式,通过JSON对象存储用户声明信息(如用户ID、角色、过期时间),并通过数字签名保证信息完整性。服务器无需存储Token,仅通过验证签名即可确认身份。

2. 核心组成:三部分构成的"完整凭证"

JWT由三部分组成,用.分隔,每部分均为Base64编码的字符串:

复制代码
Header.Payload.Signature  
# 示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c  
(1)Header(头部)

声明Token类型和签名算法,如:

json 复制代码
{ "alg": "HS256", "typ": "JWT" }  
# alg:签名算法(如HS256、RS256);typ:令牌类型(固定为JWT)  

经Base64Url编码后形成第一部分。

(2)Payload(载荷)

存储用户声明信息,分三类:

  • 标准声明 (可选):如iss(签发者)、exp(过期时间)、sub(用户ID)、iat(签发时间);
  • 公共声明 :自定义公开信息(如usernamerole);
  • 私有声明 :客户端与服务器约定的敏感信息(需加密)。
    示例:
json 复制代码
{ "sub": "123456", "username": "zhangsan", "exp": 1717267200 }  

经Base64Url编码后形成第二部分(注意:Base64编码可逆,请勿存放敏感信息!)。

(3)Signature(签名)

通过Header指定的算法(如HS256),对编码后的Header、Payload和服务器密钥(Secret)进行加密,生成签名:

复制代码
Signature = HS256( Base64UrlEncode(Header) + "." + Base64UrlEncode(Payload), Secret )  

签名用于验证Token是否被篡改,是JWT安全的核心。

3. 工作原理:"生成-签名-验证"的无状态流程

JWT的认证流程无需外部存储,核心是通过签名确保信息可信:

JWT认证流程详解
  1. 用户登录:前端提交账号密码,服务器验证通过后,生成Header和Payload;
  2. 生成签名:用服务器密钥(Secret)对Header和Payload进行签名,拼接为JWT返回给客户端;
  3. 客户端存储JWT:存入Cookie或LocalStorage;
  4. 后续请求验证 :客户端请求时携带JWT,服务器接收后:
    • 分离Header、Payload、Signature;
    • 用相同密钥和算法重新计算签名,对比是否与接收的Signature一致(验证未篡改);
    • 检查Payload中的exp(过期时间)、iss(签发者)等声明(验证有效性);
    • 验证通过后,直接从Payload中提取用户信息(如sub用户ID),无需查询数据库。

客户端 服务器 1. 登录请求(账号密码) 2. 验证身份\n3. 生成Header+Payload并签名生成JWT 4. 返回JWT 5. 后续API请求(携带JWT) 6. 验证JWT签名及声明(如exp, iss) 7. 返回请求资源 客户端 服务器

4. 优缺点:无状态高效,但灵活性受限

优点
  • 无状态:服务器无需存储Token,减轻Redis/数据库压力,支持高并发和水平扩展;
  • 自包含:Payload携带用户信息,减少数据库查询,提升响应速度;
  • 跨语言/跨域:基于JSON和Base64,支持多语言解析,适用于分布式系统和跨域场景。
缺点
  • 无法主动吊销:JWT生成后无法修改,若需强制登出(如账号被盗),需等待Token自然过期(或结合黑名单机制,违背无状态初衷);
  • Payload安全风险:Base64编码可逆,若存放敏感信息(如手机号),需用非对称加密(如RS256);
  • Token体积较大:Payload信息越多,JWT越长,可能增加网络传输开销。

三、传统Token与JWT的核心区别

对比维度 传统Token JWT
本质 随机字符串凭证 包含声明的自验证令牌
存储依赖 依赖Redis/数据库存储 无需存储(自包含)
验证方式 查询存储系统确认有效性 本地验证签名和声明
状态性 有状态(需记录Token状态) 无状态(Token自带所有信息)
灵活性 支持主动吊销、动态过期 无法修改,过期不可控
性能 依赖IO查询,性能损耗较高 本地计算验证,性能更优
适用场景 需要频繁吊销、权限动态变化 无状态、高并发、跨域认证

四、选型建议:如何选择适合的认证方案?

选传统Token:

  • 主动控制令牌生命周期:如电商平台"踢下线"功能、管理员强制登出;
  • 动态权限管理:用户权限变更需实时生效(传统Token可通过Redis更新value中的权限信息);
  • 敏感操作保护:结合Redis实现Token黑名单(如检测异常登录时临时封禁)。

选JWT:

  • 无状态架构:微服务、分布式系统,避免存储依赖(如K8s集群中的多节点认证);
  • 高并发场景:减少数据库/Redis查询,提升接口响应速度(如秒杀系统、API网关认证);
  • 跨域/跨服务认证:前后端分离、多端应用(Web/APP/小程序)共享认证状态。

传统Token和JWT并非对立关系,而是针对不同场景的技术选择。传统Token通过"存储-校验"保证灵活性,适合需要动态控制的场景;JWT通过"自包含-签名验证"实现无状态高效,适合高并发、分布式架构。

实际开发中,甚至可结合两者优势:用JWT作为传统Token的"载体",将用户基本信息存入JWT(减少查询),同时在Redis中记录Token状态(支持吊销)。最终,选型的核心是平衡安全性、性能与业务需求------没有最好的方案,只有最适合的方案。

相关推荐
诗句藏于尽头3 小时前
完成ssl不安全警告
网络协议·安全·ssl
独行soc8 小时前
#渗透测试#批量漏洞挖掘#HSC Mailinspector 任意文件读取漏洞(CVE-2024-34470)
linux·科技·安全·网络安全·面试·渗透测试
Me4神秘9 小时前
Linux国产与国外进度对垒
linux·服务器·安全
老K(郭云开)10 小时前
谷歌浏览器安全输入控件-allWebSafeInput控件
安全
Whoisshutiao10 小时前
网安-XSS-pikachu
前端·安全·网络安全
还是奇怪11 小时前
Linux - 安全排查 2
linux·运维·安全
Clownseven17 小时前
云端备份与恢复策略:企业如何选择最安全的备份解决方案
安全
薄荷椰果抹茶19 小时前
【网络安全基础】第六章---Web安全需求
安全·web安全
HumanRisk1 天前
降低网络安全中的人为风险:以人为本的路径
网络·安全·web安全
运维开发王义杰1 天前
金融安全生命线:用AWS EventBridge和CloudTrail构建主动式入侵检测系统
安全·金融·aws