Rust JWT认证库alcoholic_jwt的使用:轻量级JSON Web Token解析与验证库
alcoholic_jwt
这是一个用于使用JWKS中的密钥验证RS256 JWT的库。仅此而已,不多不少。
RS256是JWT最常用的非对称签名机制,例如在Google或Aprila的API中会遇到。
这个库的名称源于尝试使用其他Rust库实现类似功能时可能产生的副作用。
使用概述
您正在从某些使用RS256签名并在JWKS格式中提供其公钥的身份验证提供程序检索JWT。
对于在token头中提供用于签名的密钥ID(kid声明)的token示例:
extern crate alcoholic_jwt;
use alcoholic_jwt::{JWKS, Validation, validate, token_kid};
// 这里隐含的函数通常会执行HTTP-GET
// 在身份验证提供程序的JWKS-URL上,并将结果反序列化到`alcoholic_jwt::JWKS`结构体中
let jwks: JWKS = jwks_fetching_function();
let token: String = some_token_fetching_function();
// 提供了几种内置验证类型:
let validations = vec![
Validation::Issuer("auth.test.aprila.no".into()),
Validation::SubjectPresent,
];
// 如果JWKS包含多个密钥,首先需要从token头中获取正确的KID
let kid = token_kid(&token)
.expect("Failed to decode token headers")
.expect("No 'kid' claim present in token");
let jwk = jwks.find(&kid).expect("Specified key not found in set");
validate(token, jwk, validations).expect("Token validation has failed!");
底层实现
该库旨在仅使用可信赖的现成组件来完成工作。加密操作由openssl crate提供,JSON序列化由serde_json提供。
贡献
该项目在TVL monorepo中开发。要处理它,您可以使用整个存储库的本地克隆或仅克隆alcoholic_jwt子树。
请遵循TVL贡献指南。
完整示例代码
use alcoholic_jwt::{JWKS, Validation, validate, token_kid};
use serde_json::{json, from_value};
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 获取JWKS (JSON Web Key Set)
let jwks_url = "https://your-auth-provider.com/.well-known/jwks.json";
let jwks: JWKS = reqwest::get(jwks_url)
.await?
.json()
.await?;
// 2. 获取要验证的token (通常来自HTTP请求头)
let token = "your.jwt.token.here".to_string();
// 3. 定义验证规则
let validations = vec![
Validation::Issuer("your-issuer".into()),
Validation::SubjectPresent,
Validation::NotExpired,
];
// 4. 从token中提取kid
let kid = match token_kid(&token) {
Ok(Some(k)) => k,
Ok(None) => return Err("No 'kid' claim present in token".into()),
Err(e) => return Err(format!("Failed to decode token headers: {}", e).into()),
};
// 5. 在JWKS中查找对应的密钥
let jwk = jwks.find(&kid)
.ok_or("Specified key not found in set")?;
// 6. 验证token
match validate(token, jwk, validations) {
Ok(_) => println!("Token is valid!"),
Err(e) => println!("Token validation failed: {}", e),
}
Ok(())
}
这个完整示例演示了如何:
- 从身份提供者获取JWKS
- 获取待验证的JWT token
- 设置验证规则(颁发者、主题存在性、未过期)
- 从token中提取kid
- 在JWKS中查找对应的公钥
- 执行验证
注意:实际使用时需要替换示例中的URL、token和验证参数为您的实际值。
1 回复
Rust JWT认证库alcoholic_jwt的使用:轻量级JSON Web Token解析与验证库
介绍
alcoholic_jwt
是一个轻量级的Rust库,用于解析和验证JSON Web Tokens(JWT)。它提供了简单直观的API来处理JWT的验证过程,支持常见的加密算法如HS256、RS256等。
主要特点:
- 支持常见的JWT算法(HS256, HS384, HS512, RS256, RS384, RS512)
- 轻量级且易于使用
- 可验证令牌过期时间(exp)、生效时间(nbf)等标准声明
- 可自定义验证规则
完整示例代码
下面是一个完整的JWT验证示例,包含了令牌生成、验证和解码:
use alcoholic_jwt::{validate, token_decode, Validation, ValidJWT};
use serde::{Deserialize, Serialize};
use jsonwebtoken::{encode, EncodingKey, Header};
use std::time::{SystemTime, UNIX_EPOCH};
// 定义JWT声明结构体
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
company: String,
exp: u64,
role: String,
}
fn main() {
// 1. 生成JWT令牌
let token = generate_jwt_token();
println!("Generated token: {}", token);
// 2. 验证JWT令牌
validate_jwt_token(&token);
// 3. 解码令牌而不验证
decode_jwt_token(&token);
}
fn generate_jwt_token() -> String {
// 设置过期时间为1小时后
let exp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() + 3600;
// 创建声明
let claims = Claims {
sub: "1234567890".to_owned(),
company: "ACME".to_owned(),
exp,
role: "admin".to_owned(),
};
// 使用HS256算法生成令牌
encode(
&Header::default(),
&claims,
&EncodingKey::from_secret("your-256-bit-secret".as_ref()),
).unwrap()
}
fn validate_jwt_token(token: &str) {
// 验证配置
let validations = vec![
Validation::SubjectPresent,
Validation::NotExpired,
Validation::Custom(|claims| {
if claims.get("role").and_then(|v| v.as_str()) == Some("admin") {
Ok(())
} else {
Err("User is not an admin".into())
}
}),
];
// 用于HMAC验证的密钥
let secret = "your-256-bit-secret".as_bytes();
// 验证令牌
match validate(token, secret, validations) {
Ok(token_claims) => {
println!("Token is valid.");
println!("Claims: {:?}", token_claims.claims);
}
Err(e) => {
println!("Token validation failed: {:?}", e);
}
}
}
fn decode_jwt_token(token: &str) {
// 解码令牌而不验证
match token_decode::<serde_json::Value>(token) {
Ok(decoded) => {
println!("Decoded token header: {:?}", decoded.header);
println!("Decoded token claims: {:?}", decoded.claims);
}
Err(e) => println!("Failed to decode token: {}", e),
}
}
代码说明
-
令牌生成:
- 使用
jsonwebtoken
库的encode
函数生成JWT令牌 - 设置过期时间为当前时间+3600秒(1小时)
- 使用HS256算法和密钥"your-256-bit-secret"进行签名
- 使用
-
令牌验证:
- 使用
alcoholic_jwt
的validate
函数验证令牌 - 检查主题是否存在、令牌是否过期
- 自定义验证检查角色是否为"admin"
- 使用
-
令牌解码:
- 使用
token_decode
函数解码令牌而不验证 - 可以查看令牌的头信息和声明内容
- 使用
注意事项
- 生产环境中应使用更强的密钥,不要使用示例中的简单密钥
- 对于RS256等非对称算法,需要配置公钥或JWKS
- 确保正确处理验证错误
- 定期检查库的更新以修复潜在的安全问题
这个完整示例展示了alcoholic_jwt
库的主要功能,包括令牌验证、自定义验证和解码功能。