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

How to get User data in controllers? #23

Open
Cosaquee opened this issue Oct 4, 2020 · 1 comment
Open

How to get User data in controllers? #23

Cosaquee opened this issue Oct 4, 2020 · 1 comment
Labels
question Further information is requested

Comments

@Cosaquee
Copy link

Cosaquee commented Oct 4, 2020

Hi,

First of all I would like to say that this repository is a really nice example of implementing JWT for Actix. It is a really helpful resource to start playing with Actix, thank you for your work.

If you have a minute to spare would you be able to suggest how to pass JWT token to the different controllers? What I would like to achieve is to have a way of extracting user_id from incoming request to automatically create relation between models and user that is creating them in the app, without a need to send user_id with every request from frontend.

If you don't want to or do not have time to, feel free to close this issue :)

@Keksoj
Copy link

Keksoj commented Oct 5, 2020

Had the same problem when taking inspiration from this repo for my own API with actix (for training).

The JWT is embedded in the request. In a single controller that takes request: &actix_web::HttpRequest as the argument you can extract the authentication header with request.headers().get("Authorization"), then unpack the authentication header like so :

use crate::{jwt::user_token::UserToken, toolbox::errors::CustomError};
use actix_web::HttpRequest;


pub fn get_uid_from_request(request: &HttpRequest) -> Result<i32, CustomError> {
    let authen_header = match request.headers().get("Authorization") {
        Some(authen_header) => authen_header,
        None => {
            return Err(
                // the authentication middleware should have checked this already
                CustomError::new(400, "Something went very wrong".to_string()),
            );
        }
    };
    let authen_str = authen_header.to_str()?;
    if !authen_str.starts_with("bearer") && !authen_str.starts_with("Bearer") {
        return Err(CustomError::new(
            400,
            "The authentication header doesn't start with 'bearer'".to_string(),
        ));
    }
    let raw_token = authen_str[6..authen_str.len()].trim();
    let token = UserToken::decode_token(raw_token.to_string())?;
    let uid = token.uid;
    Ok(uid)
}

And call this function in a controller. As an example :

// GET HOST/persons
pub async fn find_all(
    request: HttpRequest,
    pool: web::Data<Pool>,
) -> Result<HttpResponse> {
    let uid = get_uid_from_request(&request)?;
    let persons = Person::find_all(uid, &pool)?;
    Ok(HttpResponse::Ok().json(persons))
}

Feel free to ask questions on my own repo. Happy coding :-)

@SakaDream SakaDream added the question Further information is requested label Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants