创建会话 cookie(如果不存在)并使用 axum 和 tower_cookies 保留到数据库的最佳方法?

问题描述 投票:0回答:1

我对

axum
比较陌生,我正在尝试将其用作我正在创建的服务的网络服务器。

我有一些状态,其中包含我想写入会话/会话元数据的数据库。

我希望访问任何路由的所有用户都设置会话 cookie(如果它尚未出现在标头中)。然后我想将此会话 cookie 写入数据库(以某种状态存储)。

我正在使用

tower_cookies
板条箱,试图使 cookie 读取和写入更符合人体工程学,所以我更希望中间件能够访问
Cookies
结构,而不是读取和写入原始
Request<...>
Response<...>

我所做的所有尝试在某种程度上都是不够的——要么是一个独立的处理程序(而不是自动应用于所有路由的中间件),要么不使用

Cookie
类(并处理原始
Cookie
/
Set-Cookie
直接标头),或类似不符合人体工程学的东西。我觉得这是一件很常见的事情,所以我一定错过了一些东西。对于这些不符合人体工程学但编译方法之一的精炼示例:

// Problem: not using Cookies from the CookieManager, instead dealing with the headers directly.
pub async fn set_and_store_cookie_if_absent<B>(
    State(state): State<MyState>,
    request: Request<B>,
    next: Next<B>,
) -> Response {
    // Read request cookies, create / write new session to state.db if needed
    let response = next.run(request).await;
    // Write to response cookies.
    response
}

let state = MyState::new();
Route(...)
    .layer(
        ServiceBuilder::new()
            .layer(CookieManagerLayer::new())
            .layer(middleware::from_fn_with_state(state.clone(), set_and_store_cookie_if_absent)));

但这并没有使用我想要使用的

CookieManagerLayer

rust cookies middleware rust-axum axum
1个回答
0
投票

啊,经过一些研究,我尝试的一些方法是正确的,除了我的

State
包装了一种不能很好地与异步配合的类型:https://github.com/tokio-rs/axum/discussions /964#讨论评论-2629585

所以正确的做法是这样的:

pub async fn set_and_store_cookie_if_absent<B>(
    State(state): State<MyState>,
    cookies: Cookies,
    request: Request<B>,
    next: Next<B>,
) -> Response {
    if cookies.get(SESSION_COOKIE).is_none() {
        // handle, write to State, etc.
    }
    
    next.run(request).await
}

但这给了我很多以前很难解决的错误——因为我使用的是

rusqlite
而不是
tokio-rusqlite
之类的东西。

© www.soinside.com 2019 - 2024. All rights reserved.