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

implementation of serde::de::Deserialize is not general enough #91

Open
Necoo33 opened this issue Aug 10, 2023 · 2 comments
Open

implementation of serde::de::Deserialize is not general enough #91

Necoo33 opened this issue Aug 10, 2023 · 2 comments

Comments

@Necoo33
Copy link

Necoo33 commented Aug 10, 2023

Hello, i want to make an authentication flow with your package but i take that error.

My related codes like this:

in models crate:

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

in authlogic crate:

use hmac::{Hmac, Mac};
use jwt::{SignWithKey, VerifyWithKey};
use sha2::Sha256;
use std::collections::BTreeMap;

extern crate models;

pub fn create_jwt(user_struct: models::UserForAuth, 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("user", user_struct);

    return new_claim.sign_with_key(&jwt_key).unwrap();
}

pub fn verify_jwt_and_return_values(jwt_value: &str, secret_key: &str) -> Option<models::UserForAuth> {
    let format_the_u8 = format!("b{}", secret_key);

    let new_key: Hmac<Sha256> = Hmac::new_from_slice(&format_the_u8.as_bytes()).unwrap();

    let existing_claim: BTreeMap<&str, models::UserForAuth> = jwt_value.verify_with_key(&new_key).unwrap();

    return Some(existing_claim["user"].clone());
}

and i take that error:

error: implementation of serde::de::Deserialize is not general enough
--> authlogic\src\lib.rs:22:63
|
22 | let existing_claim: BTreeMap<&str, models::UserForAuth> = jwt_value.verify_with_key(&new_key).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of serde::de::Deserialize is not general enough
|
= note: BTreeMap<&str, UserForAuth> must implement serde::de::Deserialize<'0>, for any lifetime '0...
= note: ...but it actually implements serde::de::Deserialize<'1>, for some specific lifetime '1

error: could not compile authlogic (lib) due to previous error

So how do i fix that error?

@gpollatos
Copy link

gpollatos commented Sep 24, 2023

Hey, I am very very new to Rust and I am also using this library and saw your issue. The solution in this case is to declare your existing_claim as:

let existing_claim: BTreeMap<String, models::UserForAuth> = jwt_value.verify_with_key(&new_key).unwrap();

Unfortunately I cannot in detail articulate yet why exactly &str is problematic but I started reading this post and trying to understand the why.

Furthermore in your code this part is also problematic:

let format_the_u8 = format!("b{}", secret_key);
let new_key: Hmac<Sha256> = Hmac::new_from_slice(&format_the_u8.as_bytes()).unwrap();

and results in a MACError since as afar as I understand so far b{} doesn't do the conversion you wish.

Here's a working modification of your code:

fn main() {
    let user = UserForAuth{
        id: String::from("some_id"),
        nickname: String::from("some_nickname"),
        email: String::from("some_email"),
        role: String::from("some_role"),
    };
    let tok = create_jwt(user, b"some-secret");
    let u =  verify_jwt_and_return_values(tok.as_str(), "some-secret").unwrap();
    println!("{:?}", u);
}

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

pub fn create_jwt(user_struct: UserForAuth, 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("user", user_struct);
    return new_claim.sign_with_key(&jwt_key).unwrap();
}

pub fn verify_jwt_and_return_values(jwt_value: &str, secret_key: &str) -> Option<UserForAuth> {
    let new_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()).unwrap();
    println!("{:?}", new_key);
    let result: Result<BTreeMap<String, UserForAuth>, Error> = jwt_value.verify_with_key(&new_key);
    match result {
        Ok(existing_claim) => Some(existing_claim["user"].clone()),
        Err(e) => {
            println!("{}", e);
            None
        }
    }
}

Hope it helps!

@Necoo33
Copy link
Author

Necoo33 commented Sep 24, 2023

Hey, I am very very new to Rust and I am also using this library and saw your issue. The solution in this case is to declare your existing_claim as:

let existing_claim: BTreeMap<String, models::UserForAuth> = jwt_value.verify_with_key(&new_key).unwrap();

Unfortunately I cannot in detail articulate yet why exactly &str is problematic but I started reading this post and trying to understand the why.

Furthermore in your code this part is also problematic:

let format_the_u8 = format!("b{}", secret_key);
let new_key: Hmac<Sha256> = Hmac::new_from_slice(&format_the_u8.as_bytes()).unwrap();

and results in a MACError since as afar as I understand so far b{} doesn't do the conversion you wish.

Here's a working modification of your code:

fn main() {
    let user = UserForAuth{
        id: String::from("some_id"),
        nickname: String::from("some_nickname"),
        email: String::from("some_email"),
        role: String::from("some_role"),
    };
    let tok = create_jwt(user, b"some-secret");
    let u =  verify_jwt_and_return_values(tok.as_str(), "some-secret").unwrap();
    println!("{:?}", u);
}

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

pub fn create_jwt(user_struct: UserForAuth, 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("user", user_struct);
    return new_claim.sign_with_key(&jwt_key).unwrap();
}

pub fn verify_jwt_and_return_values(jwt_value: &str, secret_key: &str) -> Option<UserForAuth> {
    let new_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()).unwrap();
    println!("{:?}", new_key);
    let result: Result<BTreeMap<String, UserForAuth>, Error> = jwt_value.verify_with_key(&new_key);
    match result {
        Ok(existing_claim) => Some(existing_claim["user"].clone()),
        Err(e) => {
            println!("{}", e);
            None
        }
    }
}

Hope it helps!

it's interesting to see. This error is most mysterious and implicit error in rust i ever seen, definitely contrary to rust's error policy. I was changed another package to solve my problem and i could implemented it successfully. I don't think to use this package anymore.

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