Trying to create a jwt verify utility function

Trying to create a small jwt verify utility function.
Following this example: jsonwebtoken/custom_header.rs at master · Keats/jsonwebtoken · GitHub

Example is this

let token_data = match decode::<Claims>(
        &token,
        &DecodingKey::from_secret(key),
        &Validation::new(Algorithm::HS512),
    ) {
        Ok(c) => c,
        Err(err) => match *err.kind() {
            ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error
            _ => panic!(),
        },
    };

My function which is not corrent at all but unable to fix this as I am not familiar with generic at all.

pub fn jwt_verify<T: Deserialize>(claim: T, str: &String) -> T {
    let jwt_secret: String = var("JWT_SECRET")
        .map_err(|_| error!("JWT_SECRET not found"))
        .unwrap_or_else(|_| "jwt-secret".to_string());

    let token_data = decode::<T>(
        str,
        &DecodingKey::from_secret(jwt_secret.as_bytes()),
        &Validation::new(Algorithm::HS512),
    );

    claim = match token_data {
        Ok(t) => t,
        _ => {
            error!("Fail to verify JWT");
            claim::default()
        }
    };

    claim
}

Thanks

It's better if you share the error message you get or describe in what way the function isn't correct. It's also useful if the code includes the imports that are required for it to compile.

I recommend reading the Rust book chapter on generics: Generic Types, Traits, and Lifetimes - The Rust Programming Language

claim: T is just a regular function parameter that happens to have a generic type. It doesn't make sense to take a claim parameter in a function that is supposed to create it, so first you'll want to remove it:

pub fn jwt_verify<T: Deserialize>(s: &str) -> T

(I also changed str: &String to s: &str because str is a confusing variable name when str is also a commonly used type, and &str is almost always better than &String because you can use it with string literals, among with other benefits)

jsonwebtoken::decode's generic type T is required to implement DeserializeOwned, not Deserialize, so that should also be what your function requires:

pub fn jwt_verify<T: DeserializeOwned>(s: &str) -> T

claim::default() doesn't make sense, because claim is just a regular variable. You can get a default value of T the same way as with other types: T::default(). This uses the Default trait, so we need to specify that T needs to implement it:

pub fn jwt_verify<T: DeserializeOwned + Default>(s: &str) -> T

Finally, decode returns a Result<TokenData<T>>, so the type of t in Ok(t) => t is not T but TokenData<T>, so you can't return it from a function that returns T.

After you fix these the function should work.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.