伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

【每周一库】- JWT的Rust实现

来源:本站原创 浏览:197次 时间:2021-07-21
sonwebtoken

Rust实现的JSON Web Token库,用于安全身份验证。

安装

将以下内容加入 Cargo.toml:

jsonwebtoken = "7"
serde = {version = "1.0", features = ["derive"] }

需要Rust 1.39及以上版本

算法

这个库目前支持以下算法:

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512
  • ES256
  • ES384
如何使用

引用与结构型:

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

/// 我们的声言结构型, 需要由`Serialize` 或 `Deserialize`派生
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
   sub: String,
   company: String,
   exp: usize,
}
声言

声言中可被验证的字段。

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
   aud: String,         // 可选。听众
   exp: usize,          // 必须。(validate_exp 在验证中默认为真值)。截止时间 (UTC 时间戳)
   iat: usize,          // 可选。发布时间 (UTC 时间戳)
   iss: String,         // 可选。发布者
   nbf: usize,          // 可选。不早于 (UTC 时间戳)
   sub: String,         // 可选。标题 (令牌指向的人)
}
标头

默认算法是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()))?;
编码
// 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 结构型
  • 某些声言: 你定义的结构型
  • 一个key或secret

当使用HS256,HS2384或HS512时,密钥始终是共享机密,如上例所示。使用RSA / EC时,密钥应始终是PEM或DER格式的私钥内容。如果密钥是PEM格式,则最好以lazy_static或类似的方式生成一次EncodingKey,然后重复使用,以实现更好的性能。

解码
// `token` 是一个有两个参数的结构型: `标头` 和 `声言` (`声言` 为你自己定义的结构型)
let token = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::default())?;

解码 会因以下原因产生错误:

  • 令牌或它对应的签名是无效的
  • 令牌是无效的base64字符串
  • 至少有一个预定的声言验证失败

与编码一样,使用HS256,HS2384或HS512时,密钥始终像上面的示例一样是共享机密。使用RSA / EC时,密钥应始终是PEM或DER格式的公共密钥的内容。在某些情况下,例如,如果你不知道所使用的算法或需要获取kid,则可以选择仅解码标头:

let header = decode_header(&token)?;

这不会执行任何签名验证或验证令牌声明。你还可以使用base64格式的RSA密钥的公钥组件对令牌进行解码。主要用例为JWK,其中公钥采用JSON格式,如下所示:

{
  "kty":"RSA",
  "e":"AQAB",
  "kid":"6a7a119f-0876-4f7e-8d0f-bf3ea1391dd8",
  "n":"yRE6rHuNR0QbHO3H3Kt2pOKGVhQqGZXInOduQNxXzuKlvQTLUTv4l4sggh5_CYYi_cvI-SXVT9kPWSKXxJXBXd_4LkvcPuUakBoAkfh-eiFVMh2VrUyWyj3MFl0HTVF9KwRXLAcwkREiS3npThHRyIxuy0ZMeZfxVL5arMhw1SRELB8HoGfG_AtH89BIE9jDBHZ9dLelK9a184zAf8LwoPLxvJb3Il5nncqPcSfKDDodMFBIMc4lQzDKL5gvmiXLXB1AGLm8KBjfE8s3L5xqi-yUod-j8MtvIj812dkS4QMiRVN_by2h3ZY8LYVGrqZXZTcgn2ujn8uKjXLZVD5TdQ"
}
// `token` 是一个有两个参数的结构型: `标头` 和 `声言` (`声言` 为你自己定义的结构型)
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结构型中设置期望值。时钟偏差会让验证时间字段比较麻烦,你可以通过设置leeway字段为iatexpnbf验证添加一些余地。最后需要注意的一点是,如果不使用HS256,则需要设置此令牌允许的算法。

#[derive(Debug, Clone, PartialEq)]
struct Validation {
   pub leeway: u64,                    // Default: 0
   pub validate_exp: bool,             // Default: true
   pub validate_nbf: bool,             // Default: false
   pub aud: Option<HashSet<String>>,   // Default: None
   pub iss: Option<String>,            // Default: No��ȭ,��ȭne
   pub sub: Option<String>,            // Default: None
   pub algorithms: Vec<Algorithm>,     // Default: vec![Algorithm::HS256]
}
use jsonwebtoken::{Validation, Algorithm};

// 默认验证:唯一允许的算法是HS256
let validation = Validation::default();
// 快速设置验证的方法,只需更改算法即可
let validation = Validation::new(Algorithm::HS512);
// 为exp和nbf检查添加一些余地(以秒为单位)
let mut validation = Validation {leeway: 60, ..Default::default()};
// 检查发布者
let mut validation = Validation {iss: Some("issuer".to_string()), ..Default::default()};
// 设置听众
let mut validation = Validation::default();
validation.set_audience(&"Me"); // string
validation.set_audience(&["Me", "You"]); // array of strings



  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net