actix-web-rest-api-with-jwt
actix-web-rest-api-with-jwt copied to clipboard
How to get User data in controllers?
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 :)
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 :-)