gpt4 book ai didi

rust - 我应该如何在 rust 中为 jsonwebtokens 强制执行反序列化类型?

转载 作者:行者123 更新时间:2023-11-29 08:19:46 27 4
gpt4 key购买 nike

下面是我使用jsonwebtoken创建的token创建工具。我想以某种方式强制执行预期的 token 类型,这样如果我传入 token 字符串并告诉它我期望的声明集,它就不会返回成功的结果。

下面包括测试用例,其中包含关于我认为该服务应该在哪里失败的注释,以及代码中我认为应该发生断言的注释。

我如何强制执行这些声明类型以确保我获得我想要的 token 类型?

use jwt;
use jwt::{ Header, Validation };
use std::convert::AsRef;
use serde::de::DeserializeOwned;
use serde::Serialize;

#[derive(Debug, Serialize, Deserialize, PartialEq)]
enum TokenType {
User,
Reg,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct RegisterClaims {
typ:TokenType,
org_name:String,
name:String,
email:String,
exp: usize,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct UserClaims {
typ:TokenType,
usr_id:String,
sub:String,
exp: usize,
}

#[derive(Debug)]
pub struct InvalidToken {
cause: String,
}

pub struct TokenFactory {
secret:String,
}

impl TokenFactory {
pub fn new(secret:String) -> TokenFactory {
TokenFactory {
secret
}
}

pub fn validate<T: DeserializeOwned>(&self, raw_token:String) -> Result<T, InvalidToken> {
match jwt::decode::<T>(&raw_token, self.secret.as_ref(), &Validation::default()) {
Ok(tokendata) => {
/*
some how assert the type of T to match and return an Err if not matched
What
*/
Ok(tokendata.claims)
},
Err(err) => {
// todo: in the future check error kind and give better errors
Err(InvalidToken{
cause: err.to_string()
})
}
}
}

pub fn mint_token<T: Serialize>(&self, claims:&T) -> String {
jwt::encode(&Header::default(), claims, self.secret.as_ref()).unwrap()
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::util;
use std::borrow::Borrow;

#[test]
fn test_valid() {
let usr = UserClaims {
typ: TokenType::User,
sub:"foobar@gmail.com".to_string(),
exp:util::current_time_secs()+1,
usr_id:"usr-1234".to_string(),
};

let tf = TokenFactory::new("my_sceret".to_string());

let token = tf.mint_token(usr.borrow());

let usr_claims: UserClaims = tf.validate(token).unwrap();

assert_eq!(usr.sub, usr_claims.sub);
}

#[test]
fn test_mixed() {
let reg = RegisterClaims {
typ:TokenType::Reg,
org_name:"foo".to_string(),
name:"bar".to_string(),
email:"foobar@inc".to_string(),
exp:util::current_time_secs()+1,
};

let tf = TokenFactory::new("my_sceret".to_string());

let token = tf.mint_token(reg.borrow());

let usr_claims: UserClaims = tf.validate(token).unwrap(); // want it to fail here

assert_eq!(reg, usr_claims); // fails here
}
}

最佳答案

我最终使用的解决方案是为我拥有的每个声明结构实现以下序列。

trait ClaimType {
fn is_type() -> TokenType;
fn has_type(&self) -> TokenType;
}

然后在我的验证中我做了

if T::is_type() == tokendata.claims.has_type() {
return Ok(tokendata.claims);
}

Err(InvalidToken{
cause: "Wrong token type".to_string()
})

我确定可能有一种方法可以使用宏为我实现特征,或者让库本身强制执行一些反序列化检查。但是上面的就搞定了

关于rust - 我应该如何在 rust 中为 jsonwebtokens 强制执行反序列化类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58325600/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com