使用Rust jsonwebtoken库能否无需密钥解析JWT Token?
问题描述
我尝试用Rust的jsonwebtoken库解析JWT Token,相关代码如下:
use jsonwebtoken::{decode, DecodingKey, Validation}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { user_id: i32, device_id: String, app_id: String, exp: usize, pin: i32, } fn main() { let token = "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjkyLCJkZXZpY2VJZCI6ImYzOTQyZjU2MzUzZmFkODQyOTU2ZjQwZDNmMjY3Y2MxIiwiYXBwSWQiOiJ4U1c1YTRCYlZCIiwiZXQiOjAsInBpZCI6MTIsImV4cCI6MTY4NTI3NDMzM30.4uMrxm9iYt940RDL6UWFw2iN5y3p27w6H4ALtBBiE1ESnuyqBqznEIs1f240omN7bC7CpQoVhi73IZmxVTJjwA"; let token_data = decode::<Claims>( token, &DecodingKey::from_secret("your-secret".as_ref()), &Validation::default(), ); match token_data { Ok(_data) => println!("Claims:{:?}", _data.claims), Err(e) => println!("Error:{}", e), } }
对应的Cargo.toml配置:
[package] name = "rust-learn" version = "0.1.0" edition = "2018" [dependencies] serde = { version = "1.0.64", features = ["derive"] } serde_json = "1.0.64" rocket = { version = "0.5.0-rc.2", features = ["json"]} rust_wheel = { git = "https://github.com/jiangxiaoqiang/rust_wheel.git", branch = "diesel2.0" } jsonwebtoken = "8.3.0"
现在遇到的问题是:这个库解析JWT必须提供密钥,但我拿不到对应的密钥。而在线JWT解析工具不用密钥就能成功解析该Token,想问下在这个Rust库中能不能不用密钥解析JWT Token?
解决方案
可以实现无需密钥解析。JWT由Header、Payload、Signature三部分组成,在线工具能直接解析是因为它们仅解码前两部分(这两部分采用Base64URL编码,无需密钥),而jsonwebtoken库默认的decode方法会同时验证签名,因此需要密钥。要跳过签名验证仅解析内容,需调整Validation配置:
- 禁用签名验证:将
Validation实例的validate_signature字段设为false - 指定匹配算法:从Token Header的
alg字段可知该Token使用HS512算法,需在Validation中指定对应算法,避免算法不匹配报错
修改后的代码如下:
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { user_id: i32, device_id: String, app_id: String, exp: usize, pin: i32, } fn main() { let token = "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjkyLCJkZXZpY2VJZCI6ImYzOTQyZjU2MzUzZmFkODQyOTU2ZjQwZDNmMjY3Y2MxIiwiYXBwSWQiOiJ4U1c1YTRCYlZCIiwiZXQiOjAsInBpZCI6MTIsImV4cCI6MTY4NTI3NDMzM30.4uMrxm9iYt940RDL6UWFw2iN5y3p27w6H4ALtBBiE1ESnuyqBqznEIs1f240omN7bC7CpQoVhi73IZmxVTJjwA"; // 配置Validation规则,跳过签名验证并指定算法 let mut validation = Validation::new(Algorithm::HS512); validation.validate_signature = false; // 签名验证已禁用,密钥可随意填写 let token_data = decode::<Claims>( token, &DecodingKey::from_secret("dummy-secret".as_ref()), &validation, ); match token_data { Ok(_data) => println!("Claims:{:?}", _data.claims), Err(e) => println!("Error:{}", e), } }
注意:跳过签名验证意味着无法确认Token是否被篡改,仅适用于调试查看Token内容等无需验证真实性的场景。生产环境若需保证Token合法性,必须使用正确密钥完成签名验证。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

