swap encoding key implementation, need to not-arcode it if possible next.
This commit is contained in:
15
src/main.rs
15
src/main.rs
@@ -1,4 +1,6 @@
|
|||||||
use axum::serve;
|
use axum::serve;
|
||||||
|
use axum::Extension;
|
||||||
|
use jsonwebtoken::{DecodingKey, EncodingKey};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
@@ -8,7 +10,7 @@ use r2d2::{Pool};
|
|||||||
use r2d2_sqlite::SqliteConnectionManager;
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
use crate::utils::db_pool::{HotelPool,AppState};
|
use crate::utils::db_pool::{HotelPool,AppState};
|
||||||
use routes::create_router;
|
use routes::create_router;
|
||||||
|
use crate::utils::auth::JwtKeys;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -25,11 +27,18 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let state = AppState {
|
let state = AppState {
|
||||||
hotel_pools,
|
hotel_pools,
|
||||||
logs_pool,
|
logs_pool,
|
||||||
jwt_secret: "your_jwt_secret_key s".to_string(), // better: load from env var
|
//jwt_secret: "your_jwt_secret_key s".to_string(), // better: load from env var
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let jwt_secret = "your_jwt_secret_key".to_string();
|
||||||
|
let jwt_keys = JwtKeys {
|
||||||
|
encoding: EncodingKey::from_secret(jwt_secret.as_ref()),
|
||||||
|
decoding: DecodingKey::from_secret(jwt_secret.as_ref()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let app = create_router(state)
|
||||||
|
.layer(Extension(jwt_keys));
|
||||||
|
|
||||||
let app = create_router(state);
|
|
||||||
let listener = TcpListener::bind("0.0.0.0:3000").await?;
|
let listener = TcpListener::bind("0.0.0.0:3000").await?;
|
||||||
serve(listener, app).into_future().await?;
|
serve(listener, app).into_future().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use axum::{
|
|||||||
middleware::Next,
|
middleware::Next,
|
||||||
response::{Response, IntoResponse},
|
response::{Response, IntoResponse},
|
||||||
Json,
|
Json,
|
||||||
extract::{Path, State, FromRequest, FromRequestParts}
|
extract::{Path, State, FromRequest, FromRequestParts, Extension}
|
||||||
};
|
};
|
||||||
use axum::extract::FromRef;
|
use axum::extract::FromRef;
|
||||||
use axum::extract::Request as ExtractRequest;
|
use axum::extract::Request as ExtractRequest;
|
||||||
@@ -15,7 +15,6 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use chrono::{Utc};
|
use chrono::{Utc};
|
||||||
use rusqlite::{params, Connection, OptionalExtension};
|
use rusqlite::{params, Connection, OptionalExtension};
|
||||||
use async_trait::async_trait;
|
|
||||||
|
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
use argon2::{
|
use argon2::{
|
||||||
@@ -25,8 +24,15 @@ use argon2::{
|
|||||||
//use crate::utils::db_pool::;
|
//use crate::utils::db_pool::;
|
||||||
use crate::utils::db_pool::{HotelPool,AppState};
|
use crate::utils::db_pool::{HotelPool,AppState};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct JwtKeys {
|
||||||
|
pub encoding: EncodingKey,
|
||||||
|
pub decoding: DecodingKey,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn token_tester(
|
pub async fn token_tester(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
|
Extension(keys): Extension<JwtKeys>,
|
||||||
AuthClaims { user_id, hotel_id, username }: AuthClaims,
|
AuthClaims { user_id, hotel_id, username }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
format!(
|
format!(
|
||||||
@@ -53,7 +59,9 @@ where
|
|||||||
|
|
||||||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
||||||
// We assume your state has a `jwt_secret` field
|
// We assume your state has a `jwt_secret` field
|
||||||
|
let Extension(keys): Extension<JwtKeys> =
|
||||||
|
Extension::from_request_parts(parts, state).await.map_err(|_| (StatusCode::UNAUTHORIZED, "Missing keys".to_string()))?;
|
||||||
|
|
||||||
// 1️⃣ Extract the token from the Authorization header
|
// 1️⃣ Extract the token from the Authorization header
|
||||||
let auth_header = parts
|
let auth_header = parts
|
||||||
.headers
|
.headers
|
||||||
@@ -70,7 +78,7 @@ where
|
|||||||
// 2️⃣ Decode the token
|
// 2️⃣ Decode the token
|
||||||
let token_data = decode::<Claims>(
|
let token_data = decode::<Claims>(
|
||||||
token,
|
token,
|
||||||
&DecodingKey::from_secret("your_jwt_secret_key s".to_string().as_ref()),
|
&keys.decoding,
|
||||||
&Validation::new(Algorithm::HS256),
|
&Validation::new(Algorithm::HS256),
|
||||||
).map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid token".to_string()))?;
|
).map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid token".to_string()))?;
|
||||||
|
|
||||||
@@ -186,14 +194,15 @@ struct LoginResponse {
|
|||||||
|
|
||||||
pub async fn clean_auth_loging(
|
pub async fn clean_auth_loging(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
LoginPayload(payload): LoginPayload
|
Extension(keys): Extension<JwtKeys>,
|
||||||
|
LoginPayload(payload): LoginPayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// 1️⃣ Get a connection from logs pool
|
// 1️⃣ Get a connection from logs pool
|
||||||
let conn = match state.logs_pool.get() {
|
let conn = match state.logs_pool.get() {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error").into_response(),
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error").into_response(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_row = match conn.query_row(
|
let user_row = match conn.query_row(
|
||||||
"SELECT id, password, hotel_id, displayname FROM users WHERE username = ?1",
|
"SELECT id, password, hotel_id, displayname FROM users WHERE username = ?1",
|
||||||
params![&payload.username],
|
params![&payload.username],
|
||||||
@@ -234,7 +243,7 @@ pub async fn clean_auth_loging(
|
|||||||
let token = match encode(
|
let token = match encode(
|
||||||
&Header::default(),
|
&Header::default(),
|
||||||
&claims,
|
&claims,
|
||||||
&EncodingKey::from_secret(state.jwt_secret.as_ref()),
|
&keys.encoding
|
||||||
) {
|
) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(),
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ type HotelId = i32; // or i32 if you want numeric ids
|
|||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub hotel_pools: HotelPool,
|
pub hotel_pools: HotelPool,
|
||||||
pub logs_pool: Pool<SqliteConnectionManager>,
|
pub logs_pool: Pool<SqliteConnectionManager>,
|
||||||
pub jwt_secret: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user