15个重大版本
0.16.0 | 2022年1月9日 |
---|---|
0.15.0 | 2021年9月5日 |
0.14.0 | 2021年6月5日 |
0.13.0 | 2021年2月20日 |
0.2.0 | 2015年6月4日 |
#93 in Web编程
110,565 每月下载量
在 106 个crate中(46个直接) 使用
56KB
1K SLoC
JWT
A JSON Web Token library.
仅声明
如果你只关心声明(而不是头信息),只要验证了头信息,就可以使用几个特性和方法完成签名和验证。
签名
声明可以是任何 serde::Serialize
类型,通常通过 serde_derive
派生。
use hmac::{Hmac, Mac};
use jwt::SignWithKey;
use sha2::Sha256;
use std::collections::BTreeMap;
let key: Hmac<Sha256> = Hmac::new_from_slice(b"some-secret").unwrap();
let mut claims = BTreeMap::new();
claims.insert("sub", "someone");
let token_str = claims.sign_with_key(&key).unwrap();
assert_eq!(token_str, "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzb21lb25lIn0.5wwE1sBrs-vftww_BGIuTVDeHtc1Jsjo-fiHhDwR8m0");
验证
声明可以是任何 serde::Deserialize
类型,通常通过 serde_derive
派生。
use hmac::{Hmac, Mac};
use jwt::VerifyWithKey;
use sha2::Sha256;
use std::collections::BTreeMap;
let key: Hmac<Sha256> = Hmac::new_from_slice(b"some-secret").unwrap();
let token_str = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzb21lb25lIn0.5wwE1sBrs-vftww_BGIuTVDeHtc1Jsjo-fiHhDwR8m0";
let claims: BTreeMap<String, String> = token_str.verify_with_key(&key).unwrap();
assert_eq!(claims["sub"], "someone");
头信息和声明
如果你需要自定义头信息,可以使用 Token
结构。为了方便,提供了一个 Header
结构,用于所有常用的字段,但任何实现了 JoseHeader
的类型都可以使用。
签名
头信息和声明都必须实现 serde::Serialize
。
use hmac::{Hmac, Mac};
use jwt::{AlgorithmType, Header, SignWithKey, Token};
use sha2::Sha384;
use std::collections::BTreeMap;
let key: Hmac<Sha384> = Hmac::new_from_slice(b"some-secret").unwrap();
let header = Header {
algorithm: AlgorithmType::Hs384,
..Default::default()
};
let mut claims = BTreeMap::new();
claims.insert("sub", "someone");
let token = Token::new(header, claims).sign_with_key(&key).unwrap();
assert_eq!(token.as_str(), "eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiJzb21lb25lIn0.WM_WnPUkHK6zm6Wz7zk1kmIxz990Te7nlDjQ3vzcye29szZ-Sj47rLNSTJNzpQd_");
验证
头信息和声明都必须实现 serde::Deserialize
。
use hmac::{Hmac, Mac};
use jwt::{AlgorithmType, Header, Token, VerifyWithKey};
use sha2::Sha384;
use std::collections::BTreeMap;
let key: Hmac<Sha384> = Hmac::new_from_slice(b"some-secret").unwrap();
let token_str = "eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiJzb21lb25lIn0.WM_WnPUkHK6zm6Wz7zk1kmIxz990Te7nlDjQ3vzcye29szZ-Sj47rLNSTJNzpQd_";
let token: Token<Header, BTreeMap<String, String>, _> = VerifyWithKey::verify_with_key(token_str, &key).unwrap();
let header = token.header();
let claims = token.claims();
assert_eq!(header.algorithm, AlgorithmType::Hs384);
assert_eq!(claims["sub"], "someone");
存储
一个 Store
可以用来表示按键ID索引的一组密钥集合。目前,这仅在具有 Borrow<str>
键的 BTreeMap
和 HashMap
中自动实现。如果 specialization 插件可用,它将实现所有 Index<&str>
特性,就像之前那样。
对于特性 SignWithStore
,对于裸露的声明,将自动将密钥ID添加到头部。因为声明没有指定密钥ID的方式,所以需要一个密钥ID和声明的元组。对于令牌,将使用头部中的密钥ID来获取密钥。
对于特性 VerifyWithStore
,将从反序列化的头部中使用密钥ID来选择要使用的密钥。
use hmac::{Hmac, Mac};
use jwt::{Header, SignWithStore, Token, VerifyWithStore};
use sha2::Sha512;
use std::collections::BTreeMap;
let mut store: BTreeMap<_, Hmac<Sha512>> = BTreeMap::new();
store.insert("first_key", Hmac::new_from_slice(b"first").unwrap());
store.insert("second_key", Hmac::new_from_slice(b"second").unwrap());
let mut claims = BTreeMap::new();
claims.insert("sub", "someone");
let token_str = ("second_key", claims).sign_with_store(&store).unwrap();
assert_eq!(token_str, "eyJhbGciOiJIUzUxMiIsImtpZCI6InNlY29uZF9rZXkifQ.eyJzdWIiOiJzb21lb25lIn0.9gALQon5Mk8r4BjOZ2SJQlauGmT4WUhpN152x9dfKvkPON1VwEN09Id8vjQ0ABlfLJUTVNP36dsdrpYEZDLUcw");
let verified_token: Token<Header, BTreeMap<String, String>, _> = token_str.verify_with_store(&store).unwrap();
assert_eq!(verified_token.claims()["sub"], "someone");
assert_eq!(verified_token.header().key_id.as_ref().unwrap(), "second_key");
支持算法
通过 RustCrypto 支持纯Rust HMAC。通过OpenSSL支持RSA和ECDSA签名实现,默认未启用。必须将OpenSSL类型包装在 PKeyWithDigest
结构体中。
- HS256
- HS384
- HS512
- RS256
- RS384
- RS512
- ES256
- ES384
- ES512
依赖项
~1.3–2.5MB
~54K SLoC