Axum + JWT authentication Middleware that allows you to start building your application fast

Overview

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 example

There is one standard middleware for verifying a user via JWT -- the verify_user middleware. Its signature looks like this:

pub async fn verify_user<B>(
    mut req: Request<B>,
    key: &DecodingKey,
    validation: Validation,
    next: Next<B>,
) -> Result<Response, AuthError>

You can pass it to the route layer as shown below:

use axum_jwt_ware;

let app = Router::new()
        .route(
            "/hello",
            get(hello)
            .layer(middleware::from_fn(move |req, next| {
                let key = axum_jwt_ware::DecodingKey::from_secret(jwt_secret.as_ref());
                let validation = axum_jwt_ware::Validation::default();
                async move { axum_jwt_ware::verify_user(req, &key, validation, next).await }
        })),
    )

Login

It's possible for you to either implement your own custom Login or use the login provided by the library. The provided login uses the default Algorithm and just requires you to provide your "secret."

Here is an example of how to use the provided login:

use axum_jwt_ware::{CurrentUser, UserData};

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

impl UserData for MyUserData {
    fn get_user_by_email(&self, _email: &str) -> Option<CurrentUser> {
        // Implement the logic to fetch a user by email from your database
    }
}

let app = Router::new()
        .route(
            "/login",
            post(move |body: Json<axum_jwt_ware::RequestBody>| {
                let expiry_timestamp = Utc::now() + Duration::hours(48);
                let user_data = MyUserData;
                let jwt_secret = "secret";
                let refresh_secret = "refresh_secret";

                axum_jwt_ware::login(
                    body,
                    user_data.clone(),
                    jwt_secret,
                    refresh_secret,
                    expiry_timestamp.timestamp(),
                )
            }),
        )

If you are going to implement a custom login, make sure to use the axum_auth_ware::auth_token_encode method to generate your token. Here is an example of a login with RSA encryption:

use axum_jwt_ware::{CurrentUser, UserData, Algorithm, auth_token_encode};
let key = EncodingKey::from_rsa_pem(include_bytes!("../jwt_rsa.key")).unwrap();
let mut header = Header::new(Algorithm::RS256);
let expiry_timestamp = Utc::now() + Duration::hours(48);

let claims = Claims {
    sub: user.id,
    username: user.username.clone(),
    exp: expiry_timestamp,
};
let token = auth_token_encode(claims, header, &key).await;

Refresh token

A refresh token allows a user to login (get a new access token) without requiring them to enter their username and password (full login).

You can create your own using the auth_token_encode and auth_token_decode functions, or you can use the refresh token handler, which should look like this:

use axum_jwt_ware;

let app = Router::new()
        .route(
            "/refresh",
            post(move |body: Json<axum_jwt_ware::RefreshBody>| {

                let encoding_context = axum_jwt_ware::EncodingContext {
                    header: axum_jwt_ware::Header::default(),
                    validation: axum_jwt_ware::Validation::default(),
                    key: axum_jwt_ware::EncodingKey::from_secret("refresh_secret".as_ref()),
                };
                let decoding_context = axum_jwt_ware::DecodingContext {
                    header: axum_jwt_ware::Header::default(),
                    validation: axum_jwt_ware::Validation::default(),
                    key: axum_jwt_ware::DecodingKey::from_secret("refresh_secret".as_ref()),
                };
                let claims = axum_jwt_ware::Claims {
                    sub: "jkfajfafghjjfn".to_string(),
                    username: "ezesunday".to_string(),
                    exp: (Utc::now() + Duration::hours(48)).timestamp(),
                };

                axum_jwt_ware::refresh_token(body, encoding_context, decoding_context, claims)
            }),
        )

A more holistic example:

use crate::{
    auth,
    service::{hello, MyUserData},
};
use axum::{
    middleware,
    routing::{get, post},
    Json, Router,
};

use chrono::{Duration, Utc};

pub fn create_router() -> Router {
    let user_data = MyUserData;
    let jwt_secret = "secret";

    let app = Router::new()
        .route(
            "/hello",
            get(hello)
                .layer(middleware::from_fn(move |req, next| {
                    let key = auth::DecodingKey::from_secret(jwt_secret.as_ref());
                    let validation  = auth::Validation::default();
                    async move { auth::verify_user(req, &key, validation, next).await }
                })),
        )
        .route(
            "/login",
            post(move |body: Json<auth::RequestBody>| {
                let expiry_timestamp = Utc::now() + Duration::hours(48);

                auth::login(
                    body,
                    user_data.clone(),
                    jwt_secret,
                    expiry_timestamp.timestamp(),
                )
            }),
        );
    app
}

Example

You can find a working example in the example directory in the GitHub Repo

You're all set!

Features

  • Refresh Token
  • Login
    • You can implement your own login
    • Use the provided login
  • Authentication Middleware
  • Test

Want to contribute?

  • Create an issue
  • Fork the repo
  • Create a PR that fixes the issue
You might also like...
A cookie manager middleware built on top of tower.

tower-cookies A cookie manager middleware built on top of tower. Example With axum: use axum::{handler::get, Router}; use std::net::SocketAddr; use to

Rate limit middleware for Poem framework

Rate limit middleware for Poem framework Usage Check examples, poem-ratelimit is available on crates.io. A yaml configuration file is used to set limi

Write Rack middleware in Rust.

RacksOnRacks Write Rack middleware in Rust. This repo is a proof of concept and should be used as an example. The best way to use this at the moment w

A blazingly fast HTTP client with a magnificent request building syntax, made for humans.
A blazingly fast HTTP client with a magnificent request building syntax, made for humans.

🔗 glue Make requests, select JSON responses, nest them in other requests: A magnificent syntax for blazingly fast cli HTTP calls, made for humans. Ta

A Rust GraphQL system with full support for subscriptions and authentication that works out of the box.

Diana is a GraphQL system for Rust that's designed to work as simply as possible out of the box, without sacrificing configuration ability.

A Rust crate for managing authentication and authorization with support for multi-tenant / B2B products, powered by PropelAuth

PropelAuth Add authentication and authorization to your application. This library is meant to be used with a PropelAuth account. You can sign up and g

A simple authentication flow using Rust and Actix-web, with a PostgreSQL database and a sveltekit frontend.

Rust-auth-example This repository aims to represent a simple authentication flow using Rust and Actix-web, with a PostgreSQL database and a sveltekit

Axum web framework tutorial for beginners.

Axum Tutorial For Beginners Hello web developers! This tutorial will cover how to write simple web applications in rust with axum framework. If you ar

Yew + Axum + blog = Yab

Yew + Axum + blog = Yab

Releases(v0.1.5)
Owner
Eze Sunday
Let's make it happen
Eze Sunday
A Rust Boilerplate server with GraphQL API, Diesel, PostgreSQL, session authentication and JWT

Canduma rust Graphql A Rust authentication server with GraphQL API, Diesel, PostgreSQL session authentication and JWT This repository contains a Graph

Julien Lenne 738 Dec 28, 2022
🔎 Prometheus metrics middleware for Axum

Axum-Prometheus A Prometheus middleware to collect HTTP metrics for Axum applications. axum-prometheus relies on metrics_exporter_prometheus as a back

Péter Leéh 14 Jan 4, 2023
Rate Limiting middleware for Tower/Axum/Tonic/Hyper utilizing the governor crate

A Tower service and layer that provides a rate-limiting backend by governor. Based heavily on the work done for actix-governor. Works with Axum, Hyper

Ben Wishovich 31 Feb 15, 2023
🥠 Sessions as a `tower` and `axum` middleware.

tower-sessions ?? Sessions as a `tower` and `axum` middleware. ?? Overview This crate provides sessions, key-value pairs associated with a site visito

Max Countryman 48 Oct 11, 2023
🪪 Session-based user authentication for Axum.

axum-login ?? Session-based user authentication for Axum. ?? Overview axum-login is a Tower middleware providing session-based user authentication for

Max Countryman 99 Jan 5, 2023
axum-serde is a library that provides multiple serde-based extractors and responders for the Axum web framework.

axum-serde ?? Overview axum-serde is a library that provides multiple serde-based extractors / responses for the Axum web framework. It also offers a

GengTeng 3 Dec 12, 2023
Experiments with Rust CRDTs using Tokio web application framework Axum.

crdt-genome Synopsis Experiments with Rust CRDTs using Tokio web application framework Axum. Background Exploring some ideas of Martin Kleppmann, part

dougfort 3 Mar 18, 2022
Code template for a production Web Application using Axum: The AwesomeApp Blueprint for Professional Web Development.

AwesomeApp rust-web-app More info at: https://awesomeapp.dev/rust-web-app/ rust-web-app YouTube episodes: Episode 01 - Rust Web App - Course to Produc

null 45 Sep 6, 2023
An API project using Rust, Actix Web and JWT. *WIP*

Actix-web REST API with JWT (WIP) A simple CRUD backend app using Actix-web, Diesel and JWT Require Rust Stable Postgres Or using Docker How to run Ma

Akhil Sharma 4 Sep 21, 2023
Isolates Jibri pods from their Deployment when they start recording or livestreaming, and cleans them up when they finish.

jibri-pod-controller: A tool for managing the scaling of large Jibri deployments in Kubernetes. When managing a large Jibri deployment, you usually wa

AVStack 9 Nov 18, 2022