#jwt #token #jwk #api-token #api #private-key #derive-debug

surrealdb-jsonwebtoken

支持Wasm的jsonwebtoken临时分支

1个版本 (0个不稳定版本)

8.3.0-surreal.12023年8月29日

#539编码 中排名

Download history 3725/week @ 2024-04-21 4736/week @ 2024-04-28 4358/week @ 2024-05-05 4076/week @ 2024-05-12 3314/week @ 2024-05-19 3960/week @ 2024-05-26 3913/week @ 2024-06-02 3570/week @ 2024-06-09 3509/week @ 2024-06-16 3134/week @ 2024-06-23 2833/week @ 2024-06-30 3603/week @ 2024-07-07 3350/week @ 2024-07-14 3052/week @ 2024-07-21 3812/week @ 2024-07-28 3492/week @ 2024-08-04

14,008 每月下载次数
57 个crate(6 个直接) 中使用

MIT 许可证

105KB
2K SLoC

jsonwebtoken

docs.rs上的API文档

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

安装

将以下内容添加到Cargo.toml

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

最低要求的Rust版本是1.56。

算法

该库目前支持以下算法

  • 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需要3个参数

  • 一个头部: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、HS2384或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目前只支持PKCS8格式的私EC密钥。如果您的密钥顶部有BEGIN EC PRIVATE KEY,则这是一个SEC1类型,可以转换为PKCS8,如下所示:

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

验证

此库会自动验证exp声明,如果存在,则会验证nbf。您还可以验证subissaud,但这些需要在Validation结构中设置预期值。

由于验证时间字段总是有点棘手,因为存在时钟偏差,您可以通过设置leeway字段,为iatexpnbf验证添加一些容差。

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

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

依赖项

~1–5.5MB
~130K SLoC