Rust中的JWT令牌:jsonwebtoken库与身份验证

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的JWT令牌:jsonwebtoken库

JSON Web Tokens (JWT) 是一种基于JSON的开放标准(RFC 7519),用于创建访问令牌。在Rust生态系统中,最流行且最稳定的JWT处理库之一是jsonwebtoken。它提供了一套完整的函数,用于创建、签名、验证和解码JWT令牌,支持对称(HS256、HS384、HS512)和非对称(RS256、RS384、RS512、ES256、ES384)加密算法。



安装与配置

首先,将依赖项添加到项目的Cargo.toml文件中:

[dependencies]jsonwebtoken = "9.3"serde = { version = "1.0", features = ["derive"] }chrono = "0.4"

serde库用于令牌数据的序列化和反序列化,而chrono简化了时间戳(exp、iat、nbf)的处理。



JWT的基本结构

JWT令牌由三部分组成:头部(header)、载荷(claims)和签名。在Rust中,这通过结构体实现:

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]struct Claims { sub: String, // 主题(通常是用户ID) exp: usize, // 过期时间(Unix时间戳) iat: usize, // 创建时间(Unix时间戳) role: String, // 自定义字段}


创建和签名JWT令牌

以下是使用HS256算法(对称加密)创建令牌的完整示例:

use jsonwebtoken::{encode, Header, EncodingKey};use chrono::Utc;

fn create_jwt(user_id: &str, secret: &str) -> Result { let now = Utc::now().timestamp() as usize; let claims = Claims { sub: user_id.to_string(), exp: now + 3600, // 令牌有效期为1小时 iat: now, role: "user".to_string(), };

let token = encode( &Header::default(), // 默认为HS256 &claims, &EncodingKey::from_secret(secret.as_bytes()), )?; Ok(token)}


验证和解码令牌

使用decode函数并指定算法和密钥来验证令牌的真实性:

use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

fn verify_jwt(token: &str, secret: &str) -> Result { let validation = Validation::new(Algorithm::HS256); let token_data = decode::( token, &DecodingKey::from_secret(secret.as_bytes()), &validation, )?; Ok(token_data.claims)}


使用非对称算法(RS256)

对于生产环境,建议使用非对称加密。以下是RS256的示例:

use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation, Algorithm};

// 使用私钥创建令牌fn create_rs256_token(user_id: &str, private_key_pem: &str) -> Result> { let claims = Claims { sub: user_id.to_string(), exp: (Utc::now().timestamp() + 3600) as usize, iat: Utc::now().timestamp() as usize, role: "admin".to_string(), };

let token = encode( &Header::new(Algorithm::RS256), &claims, &EncodingKey::from_rsa_pem(private_key_pem.as_bytes())?, )?; Ok(token)}

// 使用公钥验证fn verify_rs256_token(token: &str, public_key_pem: &str) -> Result> { let mut validation = Validation::new(Algorithm::RS256); validation.validate_exp = true; // 检查有效期

let token_data = decode::( token, &DecodingKey::from_rsa_pem(public_key_pem.as_bytes())?, &validat

推荐