-
SummaryMy code encountered the following problem when running in layers auth.rs: use axum::{Json, Router, routing::post};
use domain::dto::user::account_login_dto::AccountLoginDTO;
use domain::vo::user::user_info_vo::UserInfoVO;
use service::user::user_service::UserService;
use std::sync::Arc;
pub fn routes() -> Router {
Router::new().route("/login", post(account_login))
}
async fn account_login(Json(payload): Json<AccountLoginDTO>) -> Result<Json<UserInfoVO>, None> {
let service = Arc::new(UserService::new());
service.user_login(payload).await
} user_service.rs: use dao::user::user_repository::get_user_by_username;
use domain::dto::user::account_login_dto::AccountLoginDTO;
use domain::vo::user::user_info_vo::UserInfoVO;
use base64::engine::general_purpose::STANDARD;
use base64::Engine as _;
use serde_json::json;
use md5;
use jsonwebtoken::{encode, EncodingKey, Header};
use aes::Aes128;
use cipher::{KeyIvInit, BlockDecryptMut};
use cbc::cipher::block_padding::Pkcs7;
use cbc::Decryptor;
use std::error::Error;
use axum::http::StatusCode;
use axum::{Json, Router};
use axum::response::{IntoResponse, Response};
use axum::routing::post;
type Aes128CbcDec = Decryptor<Aes128>;
const LOGIN_SECURITY_KEY: &[u8] = b"QsCdA/3d8CkxZ6k5c6eA61==";
const IV: &[u8; 16] = b"1234567890123456"; // 请根据实际情况调整 IV
#[derive(serde::Serialize)]
struct Claims {
sub: String,
exp: usize,
}
#[derive(Debug)]
enum AuthError {
WrongCredentials,
MissingCredentials,
TokenCreation,
InvalidToken,
}
impl IntoResponse for AuthError {
fn into_response(self) -> Response {
let (status, error_message) = match self {
AuthError::WrongCredentials => (StatusCode::UNAUTHORIZED, "Wrong credentials"),
AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, "Missing credentials"),
AuthError::TokenCreation => (StatusCode::INTERNAL_SERVER_ERROR, "Token creation error"),
AuthError::InvalidToken => (StatusCode::BAD_REQUEST, "Invalid token"),
};
let body = Json(json!({
"error": error_message,
}));
(status, body).into_response()
}
}
pub struct UserService;
impl UserService {
pub fn new() -> Self {
UserService
}
pub async fn user_login(&self, account_login_dto: AccountLoginDTO) -> Result<Json<UserInfoVO>, AuthError> {
// Check if username or password is empty
if account_login_dto.username.is_empty() || account_login_dto.password.is_empty() {
return Err(AuthError::MissingCredentials);
}
// Decrypt the password
let encrypted_password = match STANDARD.decode(&account_login_dto.password) {
Ok(pwd) => pwd,
Err(_) => {
return Err(AuthError::MissingCredentials);
}
};
let cipher = match Aes128CbcDec::new_from_slices(LOGIN_SECURITY_KEY, IV) {
Ok(cipher) => cipher,
Err(_) => {
return Err(AuthError::MissingCredentials);
}
};
let mut buffer = encrypted_password.to_vec();
let decrypted_password = match cipher.decrypt_padded_mut::<Pkcs7>(&mut buffer) {
Ok(pwd) => pwd,
Err(_) => {
return Err(AuthError::MissingCredentials);
}
};
let decrypted_password_str = match String::from_utf8(decrypted_password.to_vec()) {
Ok(pwd) => pwd,
Err(_) => {
return Err(AuthError::MissingCredentials);
}
};
// Get user by username and password
let hashed_password = format!("{:x}", md5::compute(decrypted_password_str));
match get_user_by_username(&account_login_dto.username, &hashed_password).await {
Ok(Some(user)) => {
let token = match create_token(&account_login_dto.username) {
Ok(token) => token,
Err(_) => {
return Err(AuthError::MissingCredentials);
}
};
let user_info = UserInfoVO {
id: user.id,
name: user.name.clone(),
position: None,
email: user.email.clone(),
phone_number: None,
description: None,
user_name: None,
avatar: None,
system_language: None,
token: Some(token),
expire: Some(1694757956),
};
Ok(Json(user_info))
}
_ => Err(AuthError::MissingCredentials)
}
}
}
fn create_token(username: &str) -> Result<String, Box<dyn Error>> {
let my_claims = Claims {
sub: username.to_owned(),
exp: 10000000000,
};
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
Ok(token)
} run error info: warning: `dao` (lib) generated 3 warnings (run `cargo fix --lib -p dao` to apply 1 suggestion)
Checking api v0.1.0 (E:\Open Source\Jzow\eairp-api-v2\api)
error[E0277]: the trait bound `fn(Json<AccountLoginDTO>) -> impl Future<Output = Result<Json<utils::response::Response<UserInfoVO>>, StatusCode>> {account_login}: Handler<_, _>` is not satisfied
--> api\src\user\auth.rs:9:40
|
9 | Router::new().route("/login", post(account_login))
| ---- ^^^^^^^^^^^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(Json<AccountLoginDTO>) -> impl Future<Output = Result<Json<utils::response::Response<UserInfoVO>>, StatusCode>> {account_login}`
| |
| required by a bound introduced by this call
|
= note: Consider using `#[axum::debug_handler]` to improve the error message
= help: the following other types implement trait `Handler<T, S>`:
`Layered<L, H, T, S>` implements `Handler<T, S>`
`MethodRouter<S>` implements `Handler<(), S>`
note: required by a bound in `post`
--> C:\Users\v_jweizhao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\axum-0.8.1\src\routing\method_routing.rs:444:1
|
444 | top_level_handler_fn!(post, POST);
| ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^
| | |
| | required by a bound in this function
| required by this bound in `post`
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `api` (bin "api") due to 1 previous error axum version0.8.1 |
Beta Was this translation helpful? Give feedback.
Answered by
mladedav
Feb 6, 2025
Replies: 1 comment 3 replies
-
When I use macros, there are also errors use axum::{Json, Router, routing::post};
use domain::dto::user::account_login_dto::AccountLoginDTO;
use domain::vo::user::user_info_vo::UserInfoVO;
use service::user::user_service::UserService;
use std::sync::Arc;
use axum_macros::debug_handler;
pub fn routes() -> Router {
Router::new().route("/login", post(account_login))
}
#[debug_handler]
async fn account_login(Json(payload): Json<AccountLoginDTO>) -> Result<Json<UserInfoVO>, None> {
let service = Arc::new(UserService::new());
service.user_login(payload).await
} Axum is really difficult to get started with, I'm considering switching to actix web |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can do that but it might have some impact on compilation times. I usually use it just when there's an error like yours and after fixing it I remove them but that can be just preference.
Feel free to post the errors if you need more help.