首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Axum:将参数传递给处理程序

Axum:将参数传递给处理程序
EN

Stack Overflow用户
提问于 2022-11-01 00:28:58
回答 1查看 255关注 0票数 1

这里生锈了。我正在尝试构建一个简单的服务器来提供和解码JWT令牌,但我缺少了一个很大的部分。以下是代码:

代码语言:javascript
复制
pub struct Server {
    pub host: String,
    pub port: String,
    pub public_key: String,
    pub private_key: String
}

impl Server {
    pub async fn start(&self) {
      let routes = Router::new()
        .route("/", get(check))
        .route("/auth", post(auth));
      let mut hostport = String::from(&self.host);
      hostport.push_str(":");
      hostport.push_str(&self.port);
      println!("{}", hostport);
      let addr : SocketAddr = hostport.parse().expect("invalid host:port pair");
      axum::Server::bind(
          &addr
      ).serve(routes.into_make_service()).await.unwrap();
    }
}

async fn auth(Json(payload): Json<LoginInput>) -> impl IntoResponse {
  let claims = Claims::create(Duration::from_hours(1));
  RS384PublicKey::from_pem("id_like_to_put_Server::public_key_here").sign(claims)?;
  let lo = LoginOutput{
    token: payload.username
  };
  (StatusCode::OK, Json(lo))
}

如您所见,Server保存路由逻辑并应用配置。在配置中,我想使用一个公钥来对JWT令牌进行签名(我正在使用jwt_simple来实现这一点)。因为公钥是Server的属性,所以我想将这个值传递给auth处理程序,但是我不知道如何做到这一点。我如何将一个参数传递给Axum处理程序并在其中生成令牌呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-02 08:31:43

虽然下面是使用扩展和状态的示例,但更倾向于使用Axum文档中的State:

如果可能的话,

您应该更喜欢使用状态,因为它更具有类型安全性。缺点是它的动态性不如请求扩展。

在Cargo.toml中:

代码语言:javascript
复制
[dependencies]
axum = "0.6.0-rc.2"
serde = { version = "1.0.147", features = ["derive"] }
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }

使用状态的

代码语言:javascript
复制
use std::net::SocketAddr;

use axum::{
    extract::State,
    response::IntoResponse,
    routing::{get, post},
    Json, Router,
};
use serde::Deserialize;

#[derive(Clone)]
pub struct ServerConfig {
    pub host: String,
    pub port: String,
    pub public_key: String,
    pub private_key: String,
}

#[derive(Deserialize)]
pub struct LoginInput {
    username: String,
    password: String,
}

#[tokio::main]
async fn main() {
    let server_config = ServerConfig {
        host: "0.0.0.0".into(),
        port: "8080".into(),
        public_key: "public_key".into(),
        private_key: "private_key".into(),
    };

    let addr: SocketAddr = format!("{}:{}", server_config.host, server_config.port)
        .parse()
        .unwrap();

    let routes = Router::with_state(server_config) // state will be available to all the routes
        .route("/", get(check))
        .route("/auth", post(auth));

    axum::Server::bind(&addr)
        .serve(routes.into_make_service())
        .await
        .unwrap();
}

async fn check() -> &'static str {
    "check"
}

async fn auth(
    State(server_config): State<ServerConfig>, // extract state in this handler
    // `Json` supports any type that implements `serde::Deserialize`
    Json(payload): Json<LoginInput>,
) -> impl IntoResponse {
    // use server_config and payload to run the `auth` logic
    println!("host: {}", server_config.host);

    "jwt"
}

使用扩展

代码语言:javascript
复制
use std::net::SocketAddr;

use axum::{
    response::IntoResponse,
    routing::{get, post},
    Extension, Json, Router,
};
use serde::Deserialize;

#[derive(Clone)]
pub struct ServerConfig {
    pub host: String,
    pub port: String,
    pub public_key: String,
    pub private_key: String,
}

#[derive(Deserialize)]
pub struct LoginInput {
    username: String,
    password: String,
}

#[tokio::main]
async fn main() {
    let server_config = ServerConfig {
        host: "0.0.0.0".into(),
        port: "8080".into(),
        public_key: "public_key".into(),
        private_key: "private_key".into(),
    };

    let addr: SocketAddr = format!("{}:{}", server_config.host, server_config.port)
        .parse()
        .unwrap();

    let routes = Router::new()
        .route("/", get(check))
        .route("/auth", post(auth))
        .layer(Extension(server_config));

    axum::Server::bind(&addr)
        .serve(routes.into_make_service())
        .await
        .unwrap();
}

async fn check() -> &'static str {
    "check"
}

async fn auth(
    Extension(server_config): Extension<ServerConfig>,
    // `Json` supports any type that implements `serde::Deserialize`
    Json(payload): Json<LoginInput>,
) -> impl IntoResponse {
    // use server_config and payload to run the `auth` logic
    println!("host: {}", server_config.host);

    "jwt"
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74270324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档