Examples
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,
}
}
}