A cookie manager middleware built on top of tower.

Overview

License Crates.io Documentation

tower-cookies

A cookie manager middleware built on top of tower.

Example

With axum:

&'static str { cookies.add(Cookie::new("hello_world", "hello_world")); "Check your cookies." } ">
use axum::{handler::get, Router};
use std::net::SocketAddr;
use tower_cookies::{Cookie, CookieManagerLayer, Cookies};

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(handler))
        .layer(CookieManagerLayer::new());

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

async fn handler(cookies: Cookies) -> &'static str {
    cookies.add(Cookie::new("hello_world", "hello_world"));

    "Check your cookies."
}

A complete CRUD cookie example in examples/counter.rs

Safety

This crate uses #![forbid(unsafe_code)] to ensure everything is implemented in 100% safe Rust.

Contributing

We appreciate all kinds of contributions, thank you!

Note on README

The README.md file isn't meant to be changed directly. It instead generated from the crate's docs by the cargo-readme command:

  • Install the command if you don't have it: cargo install cargo-readme
  • Change the crate-level docs in src/lib.rs, or wrapping text in README.tpl
  • Apply the changes: cargo readme > README.md

If you have rusty-hook installed the changes will apply automatically on commit.

License

This project is licensed under the MIT license.

Comments
  • [Question] How to remove cookies?

    [Question] How to remove cookies?

    I am having some problem figuring out how to remove cookies.

    Cause you need to have the cookie in order to remove it, which to me is weird as i would expect to remove it by it's name. But if you get the cookie beforehand you can't use that cookie to remove it cause of lifetime issues. Are you supposed to just create a dummy cookie like in the Counter example?

        async fn handler(Extension(cookies): Extension<Cookies>) {
            let key = KEY.get().unwrap();
            let private_cookies = cookies.signed(key);
            cookies.remove(Cookie::new(COOKIE_NAME, ""));
        }
    
    opened by Zerowalker 13
  • Example of session while using tower_cookies and axum?

    Example of session while using tower_cookies and axum?

    See tokio-rs/axum#695

    Hi, when using the flash crate in axum, we also have to use the crate tower_cookies too for cookie management. As such, the session example in the axum repo will not work(I remember reading somewhere that tower_cookies kinda override any cookies made by other means?).

    Right now, I have no idea how to get current cookies while inside axum FromRequest implementation. When I do a cookies.list()) in the FromRequest implementation, it shows an Empty list even though there are 2 cookies that were created upon the user logging in(I can see them correctly in the browser.)

    Having an example of session using tower-cookies would be much appreciated :)

    opened by SylvainMartel 6
  • More ergonomic access to signed cookies

    More ergonomic access to signed cookies

    For implementing axum-flash I needed signed cookies to make sure third parties hadn't tampered with them. I did that like so this:

    • Creating a temporary cookie::CookieJar and a signed child jar
    • Putting a cookie into it
    • Reading the cookie again to get the now signed value
    • Writing that to tower_cookies::Cookies

    For reading the value I did same but in reverse.

    Would be nice if tower-cookies provided a more ergonomic way to do this. Perhaps adding methods similar to those found on cookies::CookieJar to create signed jars, ie CookieJar::signed and CookieJar::signed_mut.

    By the way thanks for tower-cookies. Its really nice 😊

    enhancement 
    opened by davidpdrsn 6
  • Upgrade to axum 0.6.0-rc.2

    Upgrade to axum 0.6.0-rc.2

    Hi! This is for inspiration, not for merging — axum 0.6 isn't stable yet, I just needed tower-cookies to work with it and thought y'all might be curious to look at what changes will be needed once 0.6 is stable.

    opened by fasterthanlime 3
  • Fix lifetimes in SignedCookies/PrivateCookies::get()

    Fix lifetimes in SignedCookies/PrivateCookies::get()

    Before this commit, the Key that's passed to Cookies::signed() or Cookies::private() is forced to have a static lifetime, because the returned Cookie gets self's lifetime as its lifetime parameter. Fix this by using 'static lifetime instead.

    This makes it possible e.g. to store Key in an axum Extension layer instead of a global Cell.

    opened by akheron 3
  • `set_value` doesn't  work.

    `set_value` doesn't work.

    Should change the value to login String and password String, but nothing happens.

    async fn register_new_account(
        Form(new_account): Form<Account>,
        Extension(pool): Extension<PgPool>,
        cookie: Cookies,
    ) -> impl IntoResponse {
        sqlx::query!(
            "INSERT INTO accounts (login, password) VALUES ($1, $2)",
            new_account.login,
            new_account.password
        )
        .execute(&pool)
        .await
        .unwrap();
    
        println!("SUS! {} | {}", new_account.login, new_account.password);
        cookie.get("login").unwrap().set_value(new_account.login); 
        cookie.get("password").unwrap().set_value(new_account.password);
    
        Redirect::to(Uri::from_static("/"))
    }
    

    Lines where I try to change a value.

    cookie.get("login").unwrap().set_value(new_account.login); 
    cookie.get("password").unwrap().set_value(new_account.password);
    

    Result after handler work: image

    opened by Jerrody 3
  • HTTP2 apparently allows multiple

    HTTP2 apparently allows multiple "Cookie:" header lines which seems to not work here

    I believe this line https://github.com/imbolc/tower-cookies/blob/main/src/service/mod.rs#L39 is only processing the first occurrence of the Cookie: header but apparently HTTP2 supports multiple Cookie headers (for better compression) (See https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2.5 ). Both Chrome and Safari seem to be sending them as separate cookie headers.

    Switching that line https://github.com/imbolc/tower-cookies/blob/main/src/service/mod.rs#L39 out to this hideous block seems to fix it as it just recreates the giant cookie blob and lets the rest split like normal.

            // let value = req.headers().get(header::COOKIE).cloned();
    
            let value: Vec<_> = req
                .headers()
                .get_all(header::COOKIE)
                .iter()
                .map(|a| a.to_str().unwrap())
                .collect();
            let value = value.join("; ");
            let value = Some(HeaderValue::from_str(&*value).unwrap());
    
    opened by charlesdaniel 3
  • Corrections, refactor and documentation improvements

    Corrections, refactor and documentation improvements

    Added:

    • authors to Cargo.toml.
    • categories to Cargo.toml.
    • New description to Cargo.toml.
    • New keywords to Cargo.toml.
    • homepage to Cargo.toml.

    Removed:

    • tower-layer feature.

    Corrected:

    • Cookies methods now take &self instead of &mut self.
    • Tests can now compile without default features.

    Changes:

    • Reorder Cargo.toml package fields alphabetically.
    • Badges in README.md.
    • Example in README.md.
    • Example in documentation.
    • Documentation.
    • Examples.
    • Moved some structs to new modules.

    Misc:

    • Added some files to .gitignore.
    opened by programatik29 3
  • Change private jar docs to reflect that they are also signed

    Change private jar docs to reflect that they are also signed

    Just like the underlying crate it should be clear from the documentation that the private cookie jar not only encrypts the cookies but also signs them. I have copied the docs from the underlying 'cookie' crate for the private cookies.

    opened by sweepline 2
  • Add private & signed cookies example

    Add private & signed cookies example

    I cannot figure out how to use private cookies. The struct is there, but I don't know how to use it. Could you please consider adding an example for it?

    opened by SaadiSave 2
  • Update to axum-core 0.1

    Update to axum-core 0.1

    This changes tower-cookies to have a public dependency on axum-core instead of axum.

    axum-core is designed to be a small crate that only contains the FromRequest and IntoResponse traits. Because of the smaller API its less likely to receive breaking changes. Therefore its recommended for library to depend on that instead of axum.

    Note this is a breaking change since axum 0.3 doesn't know about axum-core.

    opened by davidpdrsn 2
Releases(v0.8.0)
  • v0.8.0(Nov 25, 2022)

  • v0.7.0(Jun 9, 2022)

    Before this commit, the Key that's passed to Cookies::signed() or Cookies::private() is forced to have a static lifetime, because the returned Cookie gets self's lifetime as its lifetime parameter. Now the Cookie gets static lifetime instead.

    This makes it possible e.g. to store Key in an axum Extension layer instead of a global Cell.

    Thank you @akheron :pray:

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Apr 1, 2022)

  • v0.5.1(Feb 23, 2022)

  • v0.5.0(Feb 7, 2022)

    The following deps were upgraded:

    • cookie: updated to 0.16. it is important to note that this is a breaking change because the MSRV is 1.53. This is also an important update since it bumps the transitive dependency time to 0.3 which includes a multitude of fixes and improvements
    • parking_lot: updated to 0.12. This is also a breaking change that increases the MSRV to 1.49

    Thank you @ohsayan :pray:

    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Jan 3, 2022)

    async fn handler(cookies: Cookies) -> String {
        cookies.private(&my_key).get("my_cookie").unwrap().value.into()
    }
    

    Thank you @zvkemp :pray:

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Dec 3, 2021)

    This changes tower-cookies to have a public dependency on axum-core instead of axum.

    axum-core is designed to be a small crate that only contains the FromRequest and IntoResponse traits. Because of the smaller API its less likely to receive breaking changes. Therefore its recommended for library to depend on that instead of axum.

    Note this is a breaking change since axum 0.3 doesn't know about axum-core.

    Thank you @davidpdrsn :pray:

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Nov 18, 2021)

  • v0.2.2(Nov 18, 2021)

  • v0.2.0(Oct 16, 2021)

    • Cookies methods now take &self instead of &mut self. Migration: fn handler(mut cookies: Cookies) => fn handler(cookies: Cookies)
    • Standard layer semantic. Migration: .layer(CookieLayer) => .layer(CookieManagerLayer::new())

    Thank you @programatik29 :pray:

    Source code(tar.gz)
    Source code(zip)
Owner
Imbolc
Imbolc
🥠 Sessions as a `tower` and `axum` middleware.

tower-sessions ?? Sessions as a `tower` and `axum` middleware. ?? Overview This crate provides sessions, key-value pairs associated with a site visito

Max Countryman 48 Oct 11, 2023
Ergonomic and modular web framework built with Tokio, Tower, and Hyper

axum axum is a web application framework that focuses on ergonomics and modularity. More information about this crate can be found in the crate docume

Tokio 7.9k Dec 31, 2022
A crate built on top of `axum-sessions`, implementing the CSRF Synchronizer Token Pattern

Axum Synchronizer Token Pattern CSRF prevention This crate provides a Cross-Site Request Forgery protection layer and middleware for use with the axum

null 3 Dec 15, 2022
Rate limit middleware for Poem framework

Rate limit middleware for Poem framework Usage Check examples, poem-ratelimit is available on crates.io. A yaml configuration file is used to set limi

Devs Day 5 Sep 22, 2022
🔎 Prometheus metrics middleware for Axum

Axum-Prometheus A Prometheus middleware to collect HTTP metrics for Axum applications. axum-prometheus relies on metrics_exporter_prometheus as a back

Péter Leéh 14 Jan 4, 2023
Write Rack middleware in Rust.

RacksOnRacks Write Rack middleware in Rust. This repo is a proof of concept and should be used as an example. The best way to use this at the moment w

Odin 5 Jul 11, 2023
Axum + JWT authentication Middleware that allows you to start building your application fast

axum_jwt_ware Integration Guide Simple Axum + JWT authentication middleware with implemented Login and refresh token. Goal I aim to simplify the proce

Eze Sunday 3 Dec 2, 2023
Volt - A powerful, fast and memory safe package manager for the web

Volt - A powerful, fast and memory safe package manager for the web

Volt Package Manager 811 Dec 30, 2022
Open Source command line client of VRChat Package Manager.

vrc-get Open Source command line client of VRChat Package Manager. Goals Provide Open Source command line client of VRChat Package Manager. Provide mo

null 10 Jan 26, 2023
Sōzu HTTP reverse proxy, configurable at runtime, fast and safe, built in Rust. It is awesome! Ping us on gitter to know more

Sōzu · Sōzu is a lightweight, fast, always-up reverse proxy server. Why use Sōzu? Hot configurable: Sozu can receive configuration changes at runtime

sōzu 2k Dec 30, 2022
A fast static site generator in a single binary with everything built-in. https://www.getzola.org

zola (né Gutenberg) A fast static site generator in a single binary with everything built-in. Documentation is available on its site or in the docs/co

Zola 10.1k Jan 10, 2023
Perseus is a blazingly fast frontend web development framework built in Rust with support for major rendering strategies

Perseus is a blazingly fast frontend web development framework built in Rust with support for major rendering strategies, reactivity without a virtual DOM, and extreme customizability

arctic_hen7 1.2k Jan 8, 2023
⚡ A Blazingly-Fast Static Site Generator, built with Rust.

Stuart A Blazingly-Fast Static Site Generator. Download Now » Stuart is a very fast and flexible static site generator, with build times as low as 0.1

William Henderson 5 Nov 25, 2022
A highly customizable, full scale web backend for web-rwkv, built on axum with websocket protocol.

web-rwkv-axum A axum web backend for web-rwkv, built on websocket. Supports BNF-constrained grammar, CFG sampling, etc., all streamed over network. St

Li Junyu 12 Sep 25, 2023
Rate Limiting middleware for Tower/Axum/Tonic/Hyper utilizing the governor crate

A Tower service and layer that provides a rate-limiting backend by governor. Based heavily on the work done for actix-governor. Works with Axum, Hyper

Ben Wishovich 31 Feb 15, 2023
🥠 Sessions as a `tower` and `axum` middleware.

tower-sessions ?? Sessions as a `tower` and `axum` middleware. ?? Overview This crate provides sessions, key-value pairs associated with a site visito

Max Countryman 48 Oct 11, 2023
Blazingly fast framework for in-process microservices on top of Tower ecosystem

norpc = not remote procedure call Motivation Developing an async application is often a very difficult task but building an async application as a set

Akira Hayakawa 15 Dec 12, 2022
A template with cookie cutter CLI, Program and Integration tests for Solana blockchain

About solana-cli-program template is a sample app demonstrating the creation of a minimal CLI application written in Rust to interact with Solana and

null 46 Nov 3, 2022
Ergonomic and modular web framework built with Tokio, Tower, and Hyper

axum axum is a web application framework that focuses on ergonomics and modularity. More information about this crate can be found in the crate docume

Tokio 7.9k Dec 31, 2022
Tower of Hanoi - the CLI game

Tower of Hanoi - the CLI game You can play this game online on replit. Objective Move all the discs from tower 1 to tower 3. Game dynamics There are t

Fabricio Werneck 3 Apr 14, 2022