首页 > 解决方案 > 使用 Rocket 在 Rust 中取消设置会话 Cookie

问题描述

到目前为止,我无法通过logout在 Rocket 中创建的端点取消设置会话。

下面是创建 cookie 的代码:

impl AuthToken {
    pub fn from_string(string: String) -> Self {
        AuthToken(string)
    }

    pub fn to_string_ptr(&self) -> &String {
        &self.0
    }

    pub fn as_cookie(&self) -> Cookie<'static> {
        let clone = self.to_string();

        Cookie::build("session-token", clone)
            .path("/")
            .same_site(SameSite::Strict)
            .http_only(true)
            .finish()
    }
}

这是试图破坏它的代码


#[post("/logout")]
pub fn logout(mut cookies: Cookies) -> APIResponse {

    cookies.remove(Cookie::named("session-token"));

    ok().data(json!({
        "success": true
    }))
}

当 POST '/signup' 或 POST '/login' 被成功调用时,cookie 会被添加。

在 Chrome devtools 中,您可以看到 POST '/login' 响应中设置的 cookie。

登录响应标头

然后我使用 POST '/logout' 注销,并得到以下响应:

注销响应标头

在这一点上,我进行了一次硬刷新。之后 GET '/get-profile' 被调用,这在注销时不应该工作,但它仍然在请求标头中发送 cookie。

在此处输入图像描述

所以似乎会话cookie没有被正确取消,在Rocket中有没有正确的方法来做到这一点?

标签: cookiesrustsession-cookieshttponlyrust-rocket

解决方案


当您查看文档时,会说以下内容:

pub fn remove(&mut self, cookie: Cookie<'static>)
[−]

Removes cookie from this collection and generates a "removal" cookies to send to the client on response. For correctness, cookie must contain the same path and domain as the cookie that was initially set. Failure to provide the initial path and domain will result in cookies that are not properly removed.

A "removal" cookie is a cookie that has the same name as the original cookie but has an empty value, a max-age of 0, and an expiration date far in the past.

这正是您查看 Set-Cookie 标头时发生的情况。我遇到的问题是删除 cookie 设置在与原始 cookie 不同的域上。确保在同一域上设置删除 cookie 后,cookie 被正确重置。

创建cookie:

        let domain = env!("DOMAIN", "DOMAIN must be set");
        let app_env = env!("APP_ENV", "APP_ENV must be set");

        let on_production = app_env == "production";

        let cookie = Cookie::build(key, value)
            .domain(domain.to_string())
            .path("/")
            .secure(on_production)
            .max_age(Duration::days(365))
            .http_only(true)
            .finish();

        cookies.add_private(cookie);

删除 cookie:


        let domain = env!("DOMAIN", "DOMAIN must be set");
        let app_env = env!("APP_ENV", "APP_ENV must be set");

        let on_production = app_env == "production";

        let cookie = Cookie::build(name, "")
            .domain("lvh.me")
            .path("/")
            .secure(on_production)
            .max_age(Duration::days(365))
            .http_only(true)
            .finish();

        cookies.remove_private(cookie);

推荐阅读