#![forbid(unsafe_code)]
#[cfg(all(feature = "pure-rust", feature = "optimal"))]
compile_error!("jwt-simple: the `optimal` feature is only available when the `pure-rust` feature is disabled - Consider disabling default Cargo features.");
#[cfg(all(not(feature = "pure-rust"), not(feature = "optimal")))]
compile_error!("jwt-simple: the `optimal` feature is required when the `pure-rust` feature is disabled - Consider enabling default Cargo features.");
pub mod algorithms;
pub mod claims;
pub mod common;
#[cfg(feature = "cwt")]
pub mod cwt_token;
#[cfg(feature = "jwe")]
pub mod jwe_header;
#[cfg(feature = "jwe")]
pub mod jwe_token;
pub mod token;
mod jwt_header;
mod serde_additions;
pub mod reexports {
pub use anyhow;
pub use coarsetime;
pub use ct_codecs;
pub use rand;
pub use serde;
pub use serde_json;
pub use thiserror;
pub use zeroize;
}
mod error;
pub use error::{Error, JWTError};
pub mod prelude {
pub use std::collections::HashSet;
pub use coarsetime::{self, Clock, Duration, UnixTimeStamp};
pub use ct_codecs::{
Base64, Base64NoPadding, Base64UrlSafe, Base64UrlSafeNoPadding, Decoder as _, Encoder as _,
};
pub use serde::{Deserialize, Serialize};
pub use crate::algorithms::*;
pub use crate::claims::*;
pub use crate::common::*;
#[cfg(feature = "cwt")]
pub use crate::cwt_token::*;
#[cfg(feature = "jwe")]
pub use crate::jwe_token::{DecryptionOptions, EncryptionOptions, JWEToken, JWETokenMetadata};
pub use crate::token::*;
mod hashset_from_strings {
use std::collections::HashSet;
pub trait HashSetFromStringsT {
fn from_strings(strings: &[impl ToString]) -> HashSet<String> {
strings.iter().map(|x| x.to_string()).collect()
}
}
impl HashSetFromStringsT for HashSet<String> {}
}
pub use hashset_from_strings::HashSetFromStringsT as _;
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
const RSA_KP_PEM: &str = r"
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyqq0N5u8Jvl+BLH2VMP/NAv/zY9T8mSq0V2Gk5Ql5H1a+4qi
3viorUXG3AvIEEccpLsW85ps5+I9itp74jllRjA5HG5smbb+Oym0m2Hovfj6qP/1
m1drQg8oth6tNmupNqVzlGGWZLsSCBLuMa3pFaPhoxl9lGU3XJIQ1/evMkOb98I3
hHb4ELn3WGtNlAVkbP20R8sSii/zFjPqrG/NbSPLyAl1ctbG2d8RllQF1uRIqYQj
85yx73hqQCMpYWU3d9QzpkLf/C35/79qNnSKa3t0cyDKinOY7JGIwh8DWAa4pfEz
gg56yLcilYSSohXeaQV0nR8+rm9J8GUYXjPK7wIDAQABAoIBAQCpeRPYyHcPFGTH
4lU9zuQSjtIq/+bP9FRPXWkS8bi6GAVEAUtvLvpGYuoGyidTTVPrgLORo5ncUnjq
KwebRimlBuBLIR/Zboery5VGthoc+h4JwniMnQ6JIAoIOSDZODA5DSPYeb58n15V
uBbNHkOiH/eoHsG/nOAtnctN/cXYPenkCfeLXa3se9EzkcmpNGhqCBL/awtLU17P
Iw7XxsJsRMBOst4Aqiri1GQI8wqjtXWLyfjMpPR8Sqb4UpTDmU1wHhE/w/+2lahC
Tu0/+sCWj7TlafYkT28+4pAMyMqUT6MjqdmGw8lD7/vXv8TF15NU1cUv3QSKpVGe
50vlB1QpAoGBAO1BU1evrNvA91q1bliFjxrH3MzkTQAJRMn9PBX29XwxVG7/HlhX
0tZRSR92ZimT2bAu7tH0Tcl3Bc3NwEQrmqKlIMqiW+1AVYtNjuipIuB7INb/TUM3
smEh+fn3yhMoVxbbh/klR1FapPUFXlpNv3DJHYM+STqLMhl9tEc/I7bLAoGBANqt
zR6Kovf2rh7VK/Qyb2w0rLJE7Zh/WI+r9ubCba46sorqkJclE5cocxWuTy8HWyQp
spxzLP1FQlsI+MESgRLueoH3HtB9lu/pv6/8JlNjU6SzovfUZ0KztVUyUeB4vAcH
pGcf2CkUtoYc8YL22Ybck3s8ThIdnY5zphCF55PtAoGAf46Go3c05XVKx78R05AD
D2/y+0mnSGSzUjHPMzPyadIPxhltlCurlERhnwPGC4aNHFcvWTwS8kUGns6HF1+m
JNnI1okSCW10UI/jTJ1avfwU/OKIBKKWSfi9cDJTt5cRs51V7pKnVEr6sy0uvDhe
u+G091HuhwY9ak0WNtPwfJ8CgYEAuRdoyZQQso7x/Bj0tiHGW7EOB2n+LRiErj6g
odspmNIH8zrtHXF9bnEHT++VCDpSs34ztuZpywnHS2SBoHH4HD0MJlszksbqbbDM
1bk3+1bUIlEF/Hyk1jljn3QTB0tJ4y1dwweaH9NvVn7DENW9cr/aePGnJwA4Lq3G
fq/IPlUCgYAuqgJQ4ztOq0EaB75xgqtErBM57A/+lMWS9eD/euzCEO5UzWVaiIJ+
nNDmx/jvSrxA1Ih8TEHjzv4ezLFYpaJrTst4Mjhtx+csXRJU9a2W6HMXJ4Kdn8rk
PBziuVURslNyLdlFsFlm/kfvX+4Cxrbb+pAGETtRTgmAoCDbvuDGRQ==
-----END RSA PRIVATE KEY-----
";
const RSA_PK_PEM: &str = r"
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqq0N5u8Jvl+BLH2VMP/
NAv/zY9T8mSq0V2Gk5Ql5H1a+4qi3viorUXG3AvIEEccpLsW85ps5+I9itp74jll
RjA5HG5smbb+Oym0m2Hovfj6qP/1m1drQg8oth6tNmupNqVzlGGWZLsSCBLuMa3p
FaPhoxl9lGU3XJIQ1/evMkOb98I3hHb4ELn3WGtNlAVkbP20R8sSii/zFjPqrG/N
bSPLyAl1ctbG2d8RllQF1uRIqYQj85yx73hqQCMpYWU3d9QzpkLf/C35/79qNnSK
a3t0cyDKinOY7JGIwh8DWAa4pfEzgg56yLcilYSSohXeaQV0nR8+rm9J8GUYXjPK
7wIDAQAB
-----END PUBLIC KEY-----
";
#[test]
fn hs384() {
let key = HS384Key::from_bytes(b"your-256-bit-secret").with_key_id("my-key-id");
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = key.authenticate(claims).unwrap();
let options = VerificationOptions {
allowed_issuers: Some(HashSet::from_strings(&["test issuer"])),
..Default::default()
};
let _claims = key
.verify_token::<NoCustomClaims>(&token, Some(options))
.unwrap();
}
#[test]
fn blake2b() {
let key = Blake2bKey::from_bytes(b"your-256-bit-secret").with_key_id("my-key-id");
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = key.authenticate(claims).unwrap();
let options = VerificationOptions {
allowed_issuers: Some(HashSet::from_strings(&["test issuer"])),
..Default::default()
};
let _claims = key
.verify_token::<NoCustomClaims>(&token, Some(options))
.unwrap();
}
#[test]
fn rs256() {
let key_pair = RS256KeyPair::from_pem(RSA_KP_PEM).unwrap();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let pk = RS256PublicKey::from_pem(RSA_PK_PEM).unwrap();
let _claims = pk.verify_token::<NoCustomClaims>(&token, None).unwrap();
let components = pk.to_components();
let hex_e = Base64::encode_to_string(components.e).unwrap();
let _e = Base64::decode_to_vec(hex_e, None).unwrap();
}
#[test]
fn ps384() {
let key_pair = PS384KeyPair::generate(2048).unwrap();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let _claims = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn es256() {
let key_pair = ES256KeyPair::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let _claims = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn es384() {
let key_pair = ES384KeyPair::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let _claims = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn es256k() {
let key_pair = ES256kKeyPair::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let _claims = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn ed25519() {
#[derive(Serialize, Deserialize)]
struct CustomClaims {
is_custom: bool,
}
let key_pair = Ed25519KeyPair::generate();
let mut pk = key_pair.public_key();
let key_id = pk.create_key_id();
let key_pair = key_pair.with_key_id(key_id);
let public_key = key_pair.public_key(); let custom_claims = CustomClaims { is_custom: true };
let claims = Claims::with_custom_claims(custom_claims, Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let options = VerificationOptions {
required_key_id: Some(key_id.to_string()),
..Default::default()
};
let claims: JWTClaims<CustomClaims> = public_key
.verify_token::<CustomClaims>(&token, Some(options))
.unwrap();
assert!(claims.custom.is_custom);
}
#[test]
fn ed25519_der() {
let key_pair = Ed25519KeyPair::generate();
let der = key_pair.to_der();
let key_pair2 = Ed25519KeyPair::from_der(&der).unwrap();
assert_eq!(key_pair.to_bytes(), key_pair2.to_bytes());
}
#[test]
fn require_nonce() {
let key = HS256Key::generate();
let mut claims = Claims::create(Duration::from_hours(1));
let nonce = claims.create_nonce();
let token = key.authenticate(claims).unwrap();
let options = VerificationOptions {
required_nonce: Some(nonce),
..Default::default()
};
key.verify_token::<NoCustomClaims>(&token, Some(options))
.unwrap();
}
#[test]
fn eddsa_pem() {
let sk_pem = "-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIMXY1NUbUe/3dW2YUoKW5evsnCJPMfj60/q0RzGne3gg
-----END PRIVATE KEY-----
";
let pk_pem = "-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAyrRjJfTnhMcW5igzYvPirFW5eUgMdKeClGzQhd4qw+Y=
-----END PUBLIC KEY-----
";
let kp = Ed25519KeyPair::from_pem(sk_pem).unwrap();
assert_eq!(kp.public_key().to_pem(), pk_pem);
}
#[test]
fn key_metadata() {
let mut key_pair = Ed25519KeyPair::generate();
let thumbprint = key_pair.public_key().sha1_thumbprint();
let key_metadata = KeyMetadata::default()
.with_certificate_sha1_thumbprint(&thumbprint)
.unwrap();
key_pair.attach_metadata(key_metadata).unwrap();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair.sign(claims).unwrap();
let decoded_metadata = Token::decode_metadata(&token).unwrap();
assert_eq!(
decoded_metadata.certificate_sha1_thumbprint(),
Some(thumbprint.as_ref())
);
let _ = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn set_header_content_type() {
let key_pair = Ed25519KeyPair::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair
.sign_with_options(
claims,
&HeaderOptions {
content_type: Some("foo".into()),
..Default::default()
},
)
.unwrap();
let decoded_metadata = Token::decode_metadata(&token).unwrap();
assert_eq!(
decoded_metadata.jwt_header.content_type.as_deref(),
Some("foo")
);
let _ = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[test]
fn set_header_signature_type() {
let key_pair = Ed25519KeyPair::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key_pair
.sign_with_options(
claims,
&HeaderOptions {
signature_type: Some("etc+jwt".into()),
..Default::default()
},
)
.unwrap();
let decoded_metadata = Token::decode_metadata(&token).unwrap();
assert_eq!(
decoded_metadata.jwt_header.signature_type.as_deref(),
Some("etc+jwt")
);
let _ = key_pair
.public_key()
.verify_token::<NoCustomClaims>(&token, None)
.unwrap();
}
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
#[test]
fn expired_token() {
let key = HS256Key::generate();
let claims = Claims::create(Duration::from_secs(1));
let token = key.authenticate(claims).unwrap();
std::thread::sleep(std::time::Duration::from_secs(2));
let options = VerificationOptions {
time_tolerance: None,
..Default::default()
};
let claims = key.verify_token::<NoCustomClaims>(&token, None);
assert!(claims.is_ok());
let claims = key.verify_token::<NoCustomClaims>(&token, Some(options));
assert!(claims.is_err());
}
#[test]
fn salt() {
let mut key = HS256Key::generate_with_salt();
let claims = Claims::create(Duration::from_secs(86400));
let token = key.authenticate(claims).unwrap();
let res = key.verify_token::<NoCustomClaims>(&token, None);
assert!(res.is_err());
let verifier_salt = key.verifier_salt().unwrap();
key.attach_salt(verifier_salt).unwrap();
key.verify_token::<NoCustomClaims>(&token, None).unwrap();
}
#[test]
fn salt2() {
let mut key = HS256Key::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key.authenticate(claims).unwrap();
key.verify_token::<NoCustomClaims>(&token, None).unwrap();
let verifier_salt = Salt::Verifier(b"salt".to_vec());
key.attach_salt(verifier_salt).unwrap();
let res = key.verify_token::<NoCustomClaims>(&token, None);
assert!(res.is_err());
}
#[test]
fn weak_key_rejected_on_authenticate() {
let key = HS256Key::from_bytes(b"short");
let claims = Claims::create(Duration::from_secs(86400));
let res = key.authenticate(claims);
assert!(res.is_err());
assert!(res.unwrap_err().to_string().contains("Weak key"));
}
#[test]
fn weak_key_rejected_on_verify() {
let valid_key = HS256Key::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = valid_key.authenticate(claims).unwrap();
let weak_key = HS256Key::from_bytes(b"11-bytes..");
let res = weak_key.verify_token::<NoCustomClaims>(&token, None);
assert!(res.is_err());
assert!(res.unwrap_err().to_string().contains("Weak key"));
}
#[test]
fn min_key_length_accepted() {
let key = HS256Key::from_bytes(b"12-bytes...!");
let claims = Claims::create(Duration::from_secs(86400));
let token = key.authenticate(claims).unwrap();
key.verify_token::<NoCustomClaims>(&token, None).unwrap();
}
#[test]
fn weak_key_rejected_hs384() {
let key = HS384Key::from_bytes(b"short");
let claims = Claims::create(Duration::from_secs(86400));
assert!(key.authenticate(claims).is_err());
}
#[test]
fn weak_key_rejected_hs512() {
let key = HS512Key::from_bytes(b"short");
let claims = Claims::create(Duration::from_secs(86400));
assert!(key.authenticate(claims).is_err());
}
#[test]
fn weak_key_rejected_blake2b() {
let key = Blake2bKey::from_bytes(b"short");
let claims = Claims::create(Duration::from_secs(86400));
assert!(key.authenticate(claims).is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_rsa_oaep() {
let decryption_key = RsaOaepDecryptionKey::generate(2048).unwrap();
let encryption_key = decryption_key.encryption_key();
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = encryption_key.encrypt(claims).unwrap();
let claims: JWTClaims<NoCustomClaims> = decryption_key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_a256kw() {
let key = A256KWKey::generate();
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = key.encrypt(claims).unwrap();
let claims: JWTClaims<NoCustomClaims> = key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_a256kw_from_bytes() {
let raw_key = [0u8; 32];
let key = A256KWKey::from_bytes(&raw_key).unwrap();
let claims = Claims::create(Duration::from_secs(86400));
let token = key.encrypt(claims).unwrap();
let key2 = A256KWKey::from_bytes(&raw_key).unwrap();
let _claims: JWTClaims<NoCustomClaims> = key2.decrypt_token(&token, None).unwrap();
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_a128kw() {
let key = A128KWKey::generate();
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = key.encrypt(claims).unwrap();
let claims: JWTClaims<NoCustomClaims> = key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_a128kw_from_bytes() {
let raw_key = [0u8; 16];
let key = A128KWKey::from_bytes(&raw_key).unwrap();
let claims = Claims::create(Duration::from_secs(86400));
let token = key.encrypt(claims).unwrap();
let key2 = A128KWKey::from_bytes(&raw_key).unwrap();
let _claims: JWTClaims<NoCustomClaims> = key2.decrypt_token(&token, None).unwrap();
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_ecdh_es_a256kw() {
let decryption_key = EcdhEsA256KWDecryptionKey::generate();
let encryption_key = decryption_key.encryption_key();
let claims = Claims::create(Duration::from_secs(86400))
.with_issuer("test issuer")
.with_audience("test audience");
let token = encryption_key.encrypt(claims).unwrap();
let claims: JWTClaims<NoCustomClaims> = decryption_key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_ecdh_es_a128kw() {
let decryption_key = EcdhEsA128KWDecryptionKey::generate();
let encryption_key = decryption_key.encryption_key();
let claims = Claims::create(Duration::from_secs(86400)).with_issuer("test issuer");
let token = encryption_key.encrypt(claims).unwrap();
let claims: JWTClaims<NoCustomClaims> = decryption_key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_custom_claims() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct CustomClaims {
user_id: u64,
role: String,
}
let key = A256KWKey::generate();
let custom = CustomClaims {
user_id: 12345,
role: "admin".to_string(),
};
let claims = Claims::with_custom_claims(custom, Duration::from_secs(86400))
.with_issuer("test issuer");
let token = key.encrypt(claims).unwrap();
let claims: JWTClaims<CustomClaims> = key.decrypt_token(&token, None).unwrap();
assert_eq!(claims.issuer, Some("test issuer".to_string()));
assert_eq!(claims.custom.user_id, 12345);
assert_eq!(claims.custom.role, "admin");
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_with_content_encryption_a128gcm() {
let key = A256KWKey::generate();
let claims = Claims::create(Duration::from_secs(86400));
let options = EncryptionOptions {
content_encryption: ContentEncryption::A128GCM,
..Default::default()
};
let token = key.encrypt_with_options(claims, &options).unwrap();
let metadata = A256KWKey::decode_metadata(&token).unwrap();
assert_eq!(metadata.encryption(), "A128GCM");
let _claims: JWTClaims<NoCustomClaims> = key.decrypt_token(&token, None).unwrap();
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_metadata_decode() {
let key = A256KWKey::generate().with_key_id("my-key");
let claims = Claims::create(Duration::from_secs(86400));
let options = EncryptionOptions {
content_type: Some("JWT".to_string()),
..Default::default()
};
let token = key.encrypt_with_options(claims, &options).unwrap();
let metadata = A256KWKey::decode_metadata(&token).unwrap();
assert_eq!(metadata.algorithm(), "A256KW");
assert_eq!(metadata.encryption(), "A256GCM");
assert_eq!(metadata.key_id(), Some("my-key"));
assert_eq!(metadata.content_type(), Some("JWT"));
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_wrong_key_fails() {
let key1 = A256KWKey::generate();
let key2 = A256KWKey::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key1.encrypt(claims).unwrap();
let result: Result<JWTClaims<NoCustomClaims>, _> = key2.decrypt_token(&token, None);
assert!(result.is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_invalid_key_size_a256kw() {
let result = A256KWKey::from_bytes(&[0u8; 16]);
assert!(result.is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_invalid_key_size_a128kw() {
let result = A128KWKey::from_bytes(&[0u8; 32]);
assert!(result.is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_rsa_key_too_small() {
let result = RsaOaepDecryptionKey::generate(1024);
assert!(result.is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_critical_header_rejected() {
use ct_codecs::{Base64UrlSafeNoPadding, Encoder};
let key = A256KWKey::generate();
let claims = Claims::create(Duration::from_secs(86400));
let token = key.encrypt(claims).unwrap();
let parts: Vec<&str> = token.split('.').collect();
let header_bytes =
ct_codecs::Base64UrlSafeNoPadding::decode_to_vec(parts[0], None).unwrap();
let mut header: serde_json::Value = serde_json::from_slice(&header_bytes).unwrap();
header["crit"] = serde_json::json!(["unknown-extension"]);
let modified_header = serde_json::to_string(&header).unwrap();
let modified_header_b64 =
Base64UrlSafeNoPadding::encode_to_string(&modified_header).unwrap();
let modified_token = format!(
"{}.{}.{}.{}.{}",
modified_header_b64, parts[1], parts[2], parts[3], parts[4]
);
let result: Result<JWTClaims<NoCustomClaims>, _> = key.decrypt_token(&modified_token, None);
assert!(result.is_err());
}
#[cfg(feature = "jwe")]
#[test]
fn jwe_malformed_inputs_no_panic() {
let key = A256KWKey::generate();
let malformed_inputs = [
"",
".",
"..",
"...",
"....",
".....",
"a]]]]]",
"a.b.c.d.e",
"?????.?????.?????.?????.?????",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0.",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0..",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0...",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0....",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0.a.b.c.d",
"not-base64!@#$.valid.valid.valid.valid",
"eyJhbGciOiJBMjU2S1cifQ.a.b.c.d",
"eyJ9.a.b.c.d",
"e30.a.b.c.d",
&"a".repeat(100000),
&format!("{}.{}.{}.{}.{}", "a".repeat(10000), "b", "c", "d", "e"),
"eyJhbGciOiJXUk9ORyIsImVuYyI6IkEyNTZHQ00ifQ.a.b.c.d",
"eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJXUk9ORyJ9.a.b.c.d",
"