Skip to main content

jwt协议

huhxAbout 3 min

jwt 的全称是JSON Web Token,它是一种json 对象。在RFC 7519中 定义为在两方之间传输信息的安全方式。由于 jwt 中的信息是经过数字签名,因为可以用作验证和信任。

它的特征

  • 短小精悍:json 数据格式,
  • 独立的:JWT 携带交换信息和身份验证所需的所有信息
  • 广泛支持:基本上所有的语言都集成支持了 jwt。比如 go, python, java, php

它的使用场景

  • 信息交换:JWT 可用于两方之间交换信息。 JWT 经过数字签名,可以在安全的公钥/私钥对中使用。使用另一端的公钥验证信息
  • 认证:JWT 可以在有效负载中包含用户信息,并可在会话中用于对用户进行身份验证。经过身份验证后,用户可以使用请求中包含的 JWT 访问应用程序中受保护的资源。因此,每个请求都将通过验证 JWT 进行身份验证。

jwt分析

jwt 包含三个部分:Header, Payload和 Signature。格式如下:
Header.Payload.Signature

jwt 的 header 至少包含两个:typ 和 alg

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "G-xpcy4LeaUR_JIw2Td_x"
}

Header 的加密算法分为两种:

  • 对称:此算法类型使用单个密钥来签名和验证 JWT 令牌。例如:HMAC 算法
  • 非对称:此算法类型使用私钥对令牌进行签名,并使用公钥来验证签名。例如:RSA 和 ECDSA 算法。

下面是一些 alg 可能的值:

AlgoDescription
HS256HMAC using SHA-256 hash algorithm
HS384HMAC using SHA-384 hash algorithm
HS512HMAC using SHA-512 hash algorithm
RS256RSASSA using SHA-256 hash algorithm
RS384RSASSA using SHA-384 hash algorithm
RS512RSASSA using SHA-512 hash algorithm
ES256ECDSA using P-256 curve and SHA-256 hash algorithm
ES384ECDSA using P-384 curve and SHA-384 hash algorithm
ES512ECDSA using P-521 curve and SHA-512 hash algorithm

header 部分就是上述的:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkcteHBjeTRMZWFVUl9KSXcyVGRfeCJ9

202403261611489110
202403261611489110

Payload

Payload,也称为 JWT claim,包含我们想要传输的所有信息。

Payload 通常包含如下信息:

  • Registered Claim: 是可选的,但建议使用,因为它们包含有关令牌的一些元数据
  • Public Claim: 是用户自定义的信息,比如用户名
  • Private Claim:
{
  "ciamId": "55y91d28vknkpub4",
  "porsche_jti": "fc8818df16f5e4e6687f835a7a90569f",
  "iss": "https://identity.porsche-preview.com/",
  "sub": "auth0|641067c168c9f4a6edcd02d1",
  "aud": [
    "https://api.porsche-preview.com",
    "https://porsche-development.porsche-development.auth0app.com/userinfo"
  ],
  "iat": 1711334932,
  "exp": 1711338532,
  "azp": "qkKIR8Jm8cLxog6Q2tcdpVOLFOcovvfq",
  "scope": "openid profile email badge cars charging climatisation dealers manageCharging manageClimatisation mbb pid:user_profile.addresses:read pid:user_profile.birthdate:read pid:user_profile.dealers:read pid:user_profile.emails:read pid:user_profile.legal:read pid:user_profile.locale:read pid:user_profile.name:read pid:user_profile.phones:read pid:user_profile.porscheid:read pid:user_profile.vehicles:read plugAndCharge ssodb vin offline_access"
}

上述中的 token 的 Payload 就是:
202403261612557631

Signature

最后一个就是签名,这个部分需要三个部分:

  • Header:
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "G-xpcy4LeaUR_JIw2Td_x"
}
  • Payload
{
  "ciamId": "55y91d28vknkpub4",
  "porsche_jti": "fc8818df16f5e4e6687f835a7a90569f",
  "iss": "https://identity.porsche-preview.com/",
  "sub": "auth0|641067c168c9f4a6edcd02d1",
  "aud": [
    "https://api.porsche-preview.com",
    "https://porsche-development.porsche-development.auth0app.com/userinfo"
  ],
  "iat": 1711334932,
  "exp": 1711338532,
  "azp": "qkKIR8Jm8cLxog6Q2tcdpVOLFOcovvfq",
  "scope": "openid profile email badge cars charging climatisation dealers manageCharging manageClimatisation mbb pid:user_profile.addresses:read pid:user_profile.birthdate:read pid:user_profile.dealers:read pid:user_profile.emails:read pid:user_profile.legal:read pid:user_profile.locale:read pid:user_profile.name:read pid:user_profile.phones:read pid:user_profile.porscheid:read pid:user_profile.vehicles:read plugAndCharge ssodb vin offline_access"
}
  • Algorithm: Header中的RS256

于是签名为:

var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
var signature = RS256(encodedString, "secret");

其中的secret是加密的私钥,一般保存在服务器上面,属于敏感信息。

FAQ

总结

参考