51个版本 (稳定)

9.3.0 2024年3月21日
9.2.0 2023年12月1日
9.1.0 2023年10月21日
8.3.0 2023年3月15日
0.2.0 2015年11月8日

#4 in Web编程

Download history 340939/week @ 2024-04-22 339148/week @ 2024-04-29 333627/week @ 2024-05-06 376125/week @ 2024-05-13 373621/week @ 2024-05-20 352605/week @ 2024-05-27 418928/week @ 2024-06-03 436650/week @ 2024-06-10 380127/week @ 2024-06-17 398155/week @ 2024-06-24 361257/week @ 2024-07-01 429346/week @ 2024-07-08 397118/week @ 2024-07-15 430669/week @ 2024-07-22 427761/week @ 2024-07-29 431256/week @ 2024-08-05

1,702,555 每月下载量
用于 995 个crate (429个直接使用)

MIT 许可证

105KB
2K SLoC

jsonwebtoken

docs.rs上的API文档

有关JSON Web Tokens的更多信息,请参阅 JSON Web Tokens

安装

将以下内容添加到Cargo.toml中

jsonwebtoken = "9"
# If you do not need pem decoding, you can disable the default feature `use_pem` that way:
# jsonwebtoken = {version = "9", default-features = false }
serde = {version = "1.0", features = ["derive"] }

最低要求的Rust版本(MSRV)是1.67。

算法

此库目前支持以下算法

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512
  • ES256
  • ES384
  • EdDSA

如何使用

完整示例位于examples目录中:一个基本示例和一个带有自定义头的示例。

关于导入和结构体

use serde::{Serialize, Deserialize};
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation, EncodingKey, DecodingKey};

/// Our claims struct, it needs to derive `Serialize` and/or `Deserialize`
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,
    company: String,
    exp: usize,
}

声明

可以验证的声明字段。(见验证

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    aud: String,         // Optional. Audience
    exp: usize,          // Required (validate_exp defaults to true in validation). Expiration time (as UTC timestamp)
    iat: usize,          // Optional. Issued at (as UTC timestamp)
    iss: String,         // Optional. Issuer
    nbf: usize,          // Optional. Not Before (as UTC timestamp)
    sub: String,         // Optional. Subject (whom token refers to)
}

头部

默认算法是HS256,它使用共享密钥。

let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;

自定义头部和更改算法

所有RFC参数都受支持,但默认头部只设置了 typalg。如果您想设置 kid 参数或更改算法,例如

let mut header = Header::new(Algorithm::HS512);
header.kid = Some("blabla".to_owned());
let token = encode(&header, &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;

请参阅 examples/custom_header.rs 以获取完整的示例。

编码

// HS256
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
// RSA
let token = encode(&Header::new(Algorithm::RS256), &my_claims, &EncodingKey::from_rsa_pem(include_bytes!("privkey.pem"))?)?;

编码JWT需要三个参数

  • 一个头部: Header 结构体
  • 一些声明:您自己的结构体
  • 一个密钥/密钥

当使用HS256、HS384或HS512时,密钥始终是上面的共享密钥。当使用RSA/EC时,密钥应该是PEM或DER格式的私钥内容。

如果您的密钥是PEM格式,则最好在 lazy_static 或类似的地方生成一次 EncodingKey 并重用它,从性能角度考虑。

解码

// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
let token = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::default())?;

decode 可能由于多种原因导致错误

  • 令牌或其签名无效
  • 令牌包含无效的 base64 编码
  • 至少一个保留声明的验证失败

与编码一样,当使用 HS256、HS384 或 HS512 时,密钥始终是一个共享密钥,例如上面示例中的情况。当使用 RSA/EC 时,密钥应该是 PEM(或在这种情况下是证书)格式中的公钥内容或 DER 格式。

在某些情况下,例如如果您不知道使用的算法或需要抓取 kid,您可以选择仅解码头部

let header = decode_header(&token)?;

这不会执行任何签名验证或验证令牌声明。

您还可以使用 RSA 密钥的公钥组件(以 base64 格式)来解码令牌。主要用例是 JWK,其中您的公钥以如下 JSON 格式存在

{
   "kty":"RSA",
   "e":"AQAB",
   "kid":"6a7a119f-0876-4f7e-8d0f-bf3ea1391dd8",
   "n":"yRE6rHuNR0QbHO3H3Kt2pOKGVhQqGZXInOduQNxXzuKlvQTLUTv4l4sggh5_CYYi_cvI-SXVT9kPWSKXxJXBXd_4LkvcPuUakBoAkfh-eiFVMh2VrUyWyj3MFl0HTVF9KwRXLAcwkREiS3npThHRyIxuy0ZMeZfxVL5arMhw1SRELB8HoGfG_AtH89BIE9jDBHZ9dLelK9a184zAf8LwoPLxvJb3Il5nncqPcSfKDDodMFBIMc4lQzDKL5gvmiXLXB1AGLm8KBjfE8s3L5xqi-yUod-j8MtvIj812dkS4QMiRVN_by2h3ZY8LYVGrqZXZTcgn2ujn8uKjXLZVD5TdQ"
}
// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
let token = decode::<Claims>(&token, &DecodingKey::from_rsa_components(jwk["n"], jwk["e"]), &Validation::new(Algorithm::RS256))?;

如果您的密钥是 PEM 格式,从性能角度考虑,最好在 lazy_static 或类似结构中一次性生成 DecodingKey 并重复使用。

将 SEC1 私钥转换为 PKCS8

jsonwebtoken 当前仅支持私 EC 密钥的 PKCS8 格式。如果您的密钥顶部有 BEGIN EC PRIVATE KEY,这是一个 SEC1 类型,可以转换为 PKCS8,如下所示

openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem

验证

此库会自动验证 exp 声明,如果存在,还会验证 nbf。您还可以验证 subissaud,但这些需要在 Validation 结构中设置预期值。在 aud 的情况下,如果令牌中有值但 Validation 中没有设置,则令牌将被拒绝。

由于时钟偏移,验证时间字段始终有点棘手,您可以通过设置 leeway 字段来为 iatexpnbf 验证添加一些宽容度。

最后但同样重要的是,如果您不使用 HS256,则需要设置此令牌允许的算法。

查看 examples/validation.rs 以获取完整的示例。

依赖项

~1–11MB
~129K SLoC