axum_jwt_ware

Crates.ioaxum_jwt_ware
lib.rsaxum_jwt_ware
version0.1.9
created_at2023-11-25 18:26:04.503905+00
updated_at2025-08-08 11:43:53.364554+00
descriptionAxum Authentication Library
homepage
repositoryhttps://github.com/ezesundayeze/axum_jwt_ware/
max_upload_size
id1048469
size47,869
Eze Sunday (ezesundayeze)

documentation

README

axum_jwt_ware Integration Guide

Simple Axum + JWT authentication middleware with implemented Login and refresh token.

Goal

I aim to simplify the process for developers/indie hackers to focus on writing their core business logic when starting a new project, rather than spending time rewriting authentication.

Installation

cargo add axum_jwt_ware

Usage

1. Implement the UserData trait

You need to create a struct and implement the UserData trait for it. This trait has two methods: get_user_by_email and verify_password. These methods are responsible for fetching a user from your database and verifying their password.

use axum_jwt_ware::{CurrentUser, UserData};
use async_trait::async_trait;

#[derive(Clone, Copy)]
pub struct MyUserData;

#[async_trait]
impl UserData for MyUserData {
    async fn get_user_by_email(&self, email: &str) -> Option<CurrentUser> {
        // Implement the logic to fetch a user by email from your database
        // This is just a placeholder; replace it with the actual implementation
        if email == "test@test.com" {
            Some(CurrentUser {
                id: "1".to_string(),
                name: "test".to_string(),
                email: "test@test.com".to_string(),
                username: "test".to_string(),
            })
        } else {
            None
        }
    }

    async fn verify_password(&self, user_id: &str, password: &str) -> bool {
        // Implement the logic to verify a user's password
        // This is just a placeholder; replace it with the actual implementation
        user_id == "1" && password == "password"
    }
}

2. Create the Authenticator

The Authenticator struct holds all the necessary configuration, such as the keys, validation, and user data implementation.

use axum_jwt_ware::{Authenticator, DecodingKey, EncodingKey, Validation};

let user_data = MyUserData;
let jwt_key = EncodingKey::from_secret("secret".as_ref());
let refresh_key = EncodingKey::from_secret("refresh_secret".as_ref());
let jwt_decoding_key = DecodingKey::from_secret("secret".as_ref());
let refresh_decoding_key = DecodingKey::from_secret("refresh_secret".as_ref());
let validation = Validation::default();

let auth = Authenticator::new(
    user_data,
    jwt_key,
    refresh_key,
    jwt_decoding_key,
    refresh_decoding_key,
    validation,
);

3. Protect your routes

You can use the Authenticator to protect your routes by calling the layer() method.

use axum::{routing::get, Router};

async fn protected_route() -> &'static str {
    "This is a protected route"
}

let app = Router::new()
    .route("/protected", get(protected_route))
    .layer(auth.layer());

Any route under the auth_layer will have access to the Claims from the JWT in the request extensions. You can extract it like this:

use axum::{Extension, Json};
use axum_jwt_ware::Claims;

async fn protected_route(Extension(claims): Extension<Claims>) -> Json<Claims> {
    Json(claims)
}

4. Implement the login handler

The Authenticator provides a login method that you can use to implement your login handler.

use axum::{routing::post, Json, Router};
use axum_jwt_ware::RequestBody;

let app = Router::new().route(
    "/login",
    post(move |body: Json<RequestBody>| async move { auth.login(body).await }),
);

5. Implement the refresh token handler

The Authenticator provides a refresh method that you can use to implement your refresh token handler.

use axum::{routing::post, Json, Router};
use axum_jwt_ware::{Claims, RefreshBody};
use chrono::{Duration, Utc};

let app = Router::new().route(
    "/refresh",
    post(move |body: Json<RefreshBody>| async move {
        let new_claims = Claims {
            sub: "jkfajfafghjjfn".to_string(),
            username: "ezesunday".to_string(),
            exp: (Utc::now() + Duration::hours(48)).timestamp(),
        };
        auth.refresh(body, Some(new_claims)).await
    }),
);

Example

You can find a working example in the examples/helloworld directory in the GitHub Repo.

Features

  • Refresh Token
  • Login
  • Authentication Middleware
  • Tests

Want to contribute?

  • Create an issue
  • Fork the repo
  • Create a PR that fixes the issue
Commit count: 29

cargo fmt