首页 > 数据库 > 数据库开发技术 > 【每周一库】- JWT的Rust实现
jsonwebtoken = "7"
serde = {version = "1.0", features = ["derive"] }
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, // 可选。标题 (令牌指向的人)
}
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
typ和alg这两个集。在你需要设置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"))?)?;
Header 结构型lazy_static或类似的方式生成一次EncodingKey,然后重复使用,以实现更好的性能。// `token` 是一个有两个参数的结构型: `标头` 和 `声言` (`声言` 为你自己定义的结构型)
let token = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::default())?;
解码 会因以下原因产生错误:kid,则可以选择仅解码标头:let header = decode_header(&token)?;
{
"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))?;
lazy_static或类似的方式生成一次DecodingKey,并且复用,这样会优化性能。jsonwebtoken目前仅支持私有EC密钥的PKCS8格式。如果你的密钥顶部带有BEGIN EC PRIVATE KEY,则为SEC1类型,可以将其转换为PKCS8,如下所示:openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem
exp声明,并验证nbf(如果存在)。你还可以验证sub,iss和aud,但是需要在Validation结构型中设置期望值。leeway字段为iat,exp和nbf验证添加一些余地。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: None
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
原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。