这里生锈了。我正在尝试构建一个简单的服务器来提供和解码JWT令牌,但我缺少了一个很大的部分。以下是代码:
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处理程序并在其中生成令牌呢?
发布于 2022-11-02 08:31:43
虽然下面是使用扩展和状态的示例,但更倾向于使用Axum文档中的State:
如果可能的话,
您应该更喜欢使用状态,因为它更具有类型安全性。缺点是它的动态性不如请求扩展。
在Cargo.toml中:
[dependencies]
axum = "0.6.0-rc.2"
serde = { version = "1.0.147", features = ["derive"] }
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }使用状态的:
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"
}使用扩展的
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"
}https://stackoverflow.com/questions/74270324
复制相似问题