Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when using generics missing field #89

Open
ilmari-h opened this issue Apr 8, 2023 · 1 comment
Open

Error when using generics missing field #89

ilmari-h opened this issue Apr 8, 2023 · 1 comment

Comments

@ilmari-h
Copy link

ilmari-h commented Apr 8, 2023

I get the error missing field exp at line 1 column 160 with the following struct using a generic parameter T in my JWT claims. The error is raised when calling verify_with_key

This is the type of my claims:

#[derive(Deserialize, Serialize, Clone)]
pub struct AuthJWT<T> {
    pub exp: usize,
    pub iat: usize,
    pub payload: T,
}

However, I get no such error when I leave out the generic T, and instead just use the exact same struct: in both cases User is the type of the payload.

#[derive(Deserialize, Serialize, Clone)]
pub struct AuthJWT {
    pub exp: usize,
    pub iat: usize,
    pub payload: User,
}

Am I missing something or is this a bug? Any help is appreciated.

@gpollatos
Copy link

gpollatos commented Sep 24, 2023

Hi, I am very very new to Rust and am using this library. I am doing something similar but can't say I see any issue. I tried adapting your snippet above and reproduce what you are reporting but it seems to be working as expected. Please have a look:

#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct User {
    pub id: String,
    pub nickname: String,
    pub email: String,
}

#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct AuthJWT<T> {
    pub exp: usize,
    pub iat: usize,
    pub payload: T,
}

fn main() {
    let user = User {
        id: String::from("some-id"),
        nickname: String::from("some-nickname"),
        email: String::from("some-email")
    };
    let claim: AuthJWT<User> = AuthJWT {
        exp: usize::MAX,
        iat: usize::MAX,
        payload: user,
    };
    let tok = create_jwt(claim, b"some-secret");
    let u = verify_jwt(tok.as_str(), "some-secret").unwrap();
    println!("{:?}", u);
}

pub fn create_jwt(c: AuthJWT<User>, secret_key: &[u8]) -> String {
    let jwt_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key).unwrap();
    let mut new_claim = BTreeMap::new();
    new_claim.insert("claim", c);
    return new_claim.sign_with_key(&jwt_key).unwrap();
}

pub fn verify_jwt(jwt_value: &str, secret_key: &str) -> Option<AuthJWT<User>> {
    let new_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()).unwrap();
    let result: Result<BTreeMap<String, AuthJWT<User>>, Error> = jwt_value.verify_with_key(&new_key);
    match result {
        Ok(existing_claim) => Some(existing_claim["claim"].clone()),
        Err(_) => None
    }
}

Output:

cargo run
...
AuthJWT { exp: 18446744073709551615, iat: 18446744073709551615, payload: User { id: "some-id", nickname: "some-nickname", email: "some-email" } }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants