#axum #jwt #postgresql #logger #routing #middleware #ip

bin+lib mll-axum-utils

一个 Axum 的工具库

11 个版本

0.2.2 2023 年 11 月 22 日
0.2.1 2023 年 11 月 20 日
0.1.22 2023 年 8 月 9 日
0.1.21 2023 年 7 月 7 日
0.1.20 2023 年 5 月 21 日

#608数据库接口

每月 38 次下载

MIT/Apache

36KB
788

示例

use axum::extract::{Path, Query};
use axum::{
    routing::{get, post},
    Extension, Router,
};
use mll_axum_utils::res::SendRes;
use mll_axum_utils::{
    database::postgres::{new_pg_pool, PgConn},
    middleware::interceptor::{self, blacklist_vec},
};
use mll_axum_utils::{
    middleware::{
        jwt::{Jwt, JwtAuth, JwtToken},
        logger::Logger,
    },
    res::Res,
    utils::{self, echo_ip_addrs},
    validator::VJsonOrForm,
};
use serde::{Deserialize, Serialize};
use std::{net::SocketAddr, vec};
use validator::Validate;

#[tokio::main]
async fn main() {
    let addr = "0.0.0.0:3000".parse().unwrap();
    echo_ip_addrs(&addr);

    let app = Router::new()
        .route("/demo/:id", get(demo))
        .route("/index", get(index))
        .route("/login", post(login))
        // .layer(Extension(new_pg_pool("database_url").await)) 设置数据库异步连接
        .layer(JwtAuth::<Claims>::new(vec!["/login"]))
        // 拦截器拦截黑名单 ip 访问
        .layer(blacklist_vec(vec!["127.0.0.1"]))
        // 访问日志记录
        .layer(Logger::default());

    axum::Server::bind(&addr)
        .serve(app.into_make_service_with_connect_info::<SocketAddr>())
        .await
        .unwrap();
}

async fn demo(Path(s): Path<String>) -> SendRes<i64> {
    Ok(Res::ok("ok", s.parse()?))
}

async fn login(VJsonOrForm(user): VJsonOrForm<User>) -> SendRes<String> {
    let token = Claims::new(user).encode()?;
    // some validation
    Ok(Res::ok("登录成功", token))
}

async fn index(Jwt(claims): Jwt<Claims>) -> &'static str {
    "身份认证成功 允许访问"
}

// async fn db_demo(PgConn(mut conn): PgConn, Jwt(claims): Jwt<Claims>) {
//     // some db handler
// }

#[derive(Debug, Clone, Default, Validate, Serialize, Deserialize)]
struct User {
    uid: u64,

    // 数据验证
    #[validate(length(min = 3, max = 24, message = "用户名长度必须在3-24之间"))]
    name: String,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
struct Claims {
    exp: u64,
    user: User,
}

impl JwtToken for Claims {
    const SECRET: &'static str = "new_key";
    const DURATION: u64 = 60 * 60 * 24; // token 有效期持续 1 天
}

impl Claims {
    fn new(user: User) -> Self {
        Self {
            exp: Self::expiration(),
            user,
        }
    }
}

依赖

~22–36MB
~660K SLoC