JWT令牌生成与验证详细实现教程
jwt是一种紧凑的身份验证和信息交换令牌其核心是三级结构头部、载荷和签名。在生成时用密钥编码头部和载荷base64url分析验证过程中的各个部分并比较签名和检查声明。使用python的pyjwt库可以很容易地实现生成和验证过程。1. 生成jwt需要定义密钥构建包含用户信息和声明的载荷并使用hs256算法编码2. 验证jwt通过解码函数验证签名、过期时间、发行人和接收人。在实际应用中jwt登录后返回客户端后续请求通过http头携带令牌完成无状态认证。在安全方面应选择合适的算法如hs256或rs256妥善管理密钥并遵循设置合理过期时间、验证iss/aud字段、避免弱密钥、防止alg篡改、解除令牌和安全存储令牌的最佳实践。JWT令牌生成与验证详细实现教程JWTJSON的全称 Web Token本质上它是一种紧凑、自我包容的方式用于在网络各方之间安全传输信息。它通常用于身份验证和信息交换特别是在无状态API的设计中它是核心组件。直率地说它是一张加密或签名的“通行证”包括您的身份信息和一些权限声明服务器不需要每次检查数据库只要验证通行证的真实性和有效性。JWT令牌生成与验证详细实现教程解决方案要实现JWT的生成和验证核心是了解其三阶段结构头部Header、载荷Payload和签名Signature。在生成时我们用Base64Url编码头部和载荷然后用密钥签名然后用点号连接这三部分。验证时反过来分析各部分用相同的密钥重新计算签名并与收到的签名进行比较同时检查载荷中的声明如过期时间。以Python为例使用PyJWT库是目前最常见、最方便的方式JWT令牌生成与验证详细实现教程1. 生成JWT令牌import jwtimport datetimeimport time# 定义秘密钥非常重要必须妥善保管SECRET_KEY 这是一个超级安全的秘密钥匙请务必更换 # 在实际应用中应读取环境变量或配置服务def generate_jwt_token(user_id: str, username: str, expires_in_minutes: int 30):生成JWT令牌。:param user_id: 唯一的用户标识符:param username: 用户名:param expires_in_minutes: 令牌过期时间(分钟):return: 生成的JWT字符串try:# 头部 (Header) 通常由库自动处理指定算法和类型# 载荷 (Payload) 包括声明信息payload {user_id: user_id,username: username,iss: your_service_name, # Issuer (签发者)aud: your_client_app, # Audience (接收者)iat: datetime.datetime.utcnow(), # Issued At (签发时间)exp: datetime.datetime.utcnow() datetime.timedelta(minutesexpires_in_minutes) # Expiration Time (过期时间)}# 编码HS256算法和秘密密钥token jwt.encode(payload, SECRET_KEY, algorithmHS256)return tokenexcept Exception as e:print(f产生JWT时出现错误 {e})return None# 示例生成# token generate_jwt_token(12345, Alice, 60)# if token:# print(f产生的JWT: {token})2. 验证JWT令牌JWT令牌生成与验证详细实现教程import jwtfrom jwt.exceptions import ExpiredSignatureError, InvalidTokenError# 密钥与生成密钥保持一致SECRET_KEY 这是一个超级安全的秘密钥匙请务必更换def verify_jwt_token(token: str):验证JWT令牌。:param token: JWT字符串需要验证:return: 验证成功返回载荷字典失败返回Nonetry:# 解码并验证令牌。verify_expTrue 默认会检查过期时间# verify_iss 和 verify_aud 也可设置为 True 验证签发者和接收者payload jwt.decode(token, SECRET_KEY, algorithms[HS256],options{verify_signature: True, verify_exp: True,verify_iss: True, verify_aud: True},issueryour_service_name, # 验证签发者audienceyour_client_app) # 验证接收者return payloadexcept ExpiredSignatureError:print(JWT令牌已过期。)return Noneexcept InvalidTokenError as e:print(fJWT令牌无效 {e})return Noneexcept Exception as e:print(f未知错误发生在JWT验证中 {e})return None# 示例验证# # 假设我们有一个token# # verified_payload verify_jwt_token(token)# # if verified_payload:# # print(f验证成功载荷: {verified_payload})在实际应用中您将在用户成功登录后生成JWT并返回到客户端。客户端将此令牌放入HTTP请求头通常是Authorization: Bearer 将其发送给服务器服务器接到请求后再调用验证函数确认请求的合法性。JWT的结构和组成部分:它长什么样当你第一次接触JWT时你可能会想这不是一串看起来不规则的字符串吗它是如何包含自己的说实话它比你想象的要简单得多但它足够聪明。一个完整的JWT字符串通常由三个部分组成它们之间有点.分隔开Header.Payload.Signature头部Header: 这部分通常是描述JWT元数据的JSON对象例如使用的签名算法alg和令牌类型typ。最常见的头部可能会这样生长:{alg: HS256,typ: JWT}alg 表示签名算法如HMAC SHA256(HS256)或RSA SHA256(RS256)。typ 说明令牌类型这里固定的是JWT。这个JSON对象将首先由Base64Url编码。载荷Payload: 这是JWT真正的“身体”包含了我们想要传输的实际信息也就是所谓的“声明”claims.声明分为三种:注册声明Registered Claims: 这些都是预定义的声明不是强制性的而是推荐使用比如 iss (issuer, 签发者), exp (expiration time, 过期时间) sub (subject, 主题), aud (audience, 接收者) 等等。它们提供互操作性。公共声明Public Claims: 您可以定义您的声明但建议使用IANA以避免冲突 JSON Web Token 定义在Registry中的公开声明。私有声明Private Claims: 这是你和用户之间的一些私人声明比如上面的例子 user_id 和 username。 载荷也是JSON对象Base64Url也会编码。签名Signature: 这是JWT安全的核心。它是通过指定算法计算的哈希值包括编码后的头部、编码后的负载以及通过指定算法计算的秘密密钥或私钥。其功能是验证发送人的身份并确保在传输过程中不会篡改令牌。 计算签名的伪代码大致如下: HMACSHA256base64Urencode(header) . Encodebase64Url(payload), secret) 签名部分保证一旦任何字节修改签名将不匹配验证导致令牌失效。当这三部分准备好并编码时它们用点号连接起来形成最终的JWT字符串。正是这种结构使JWT能够在没有服务器频繁查询数据库的情况下自包含信息从而实现了无状态认证。选择合适的签名算法和密钥管理安全的核心考虑在JWT的生成和验证中签名算法和密钥管理是与整个系统安全直接相关的关键环节。就我个人而言我认为这就像你的“通行证”印章印章的风格算法和保管印章的人密钥必须可靠否则通行证将是徒劳的。