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编程

Download history 29579/week @ 2024-03-14 24637/week @ 2024-03-21 40173/week @ 2024-03-28 25438/week @ 2024-04-04 25595/week @ 2024-04-11 24497/week @ 2024-04-18 25791/week @ 2024-04-25 24584/week @ 2024-05-02 23714/week @ 2024-05-09 24256/week @ 2024-05-16 22777/week @ 2024-05-23 24870/week @ 2024-05-30 25342/week @ 2024-06-06 28722/week @ 2024-06-13 28760/week @ 2024-06-20 23700/week @ 2024-06-27

110,565 每月下载量
106 个crate中(46个直接) 使用

MIT 许可证

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> 键的 BTreeMapHashMap 中自动实现。如果 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