Logo

dev-resources.site

for different kinds of informations.

Rust Warp: Use Cookie for Authorization

Published at
12/31/2021
Categories
rust
warp
Author
snj
Categories
2 categories in total
rust
open
warp
open
Author
3 person written this
snj
open
Rust Warp: Use Cookie for Authorization

Warp is a composable, web server in Rust. It's code is very small and focus on speed.

The fundamental building block of warp is the Filter, they can be combined and composed to express rich requirements on requests.

But it's actually not easy to use if you are not familiar with it's concept, and the type system will also scare some beginners.

For example, I actually spend some time to figure out how to use Cookie for authorization.

Suppose we have defined a Struct to represent the User:


#[derive(Debug, Deserialize)]
pub struct User {
    username: String,
    password: String,
}
Enter fullscreen mode Exit fullscreen mode

And we have a logic to authorize whether the login request has a valid username and password, the detail implementation depends on your code:

pub fn verify_user(user: &User) -> bool {
    ....
}
Enter fullscreen mode Exit fullscreen mode

The question is how to set a Cookie in response and how to verify each request after authorization.

Set a cookie

When a user send login request and passed the authorization, we use reply with with_header to set a cookie to store a token, which will be used for later requests:

 let login = warp::path!("api" / "login")
        .and(warp::post())
        .and(warp::body::json())
        .map(|user: auth::User| {
            if auth::verify_user(&user) {
                let token = auth::gen_token();
                warp::reply::with_header(
                    token.clone(),
                    "set-cookie",
                    format!("token={}; Path=/; HttpOnly; Max-Age=1209600", token),
                )
                .into_response()
            } else {
                warp::reply::with_status("failed", http::StatusCode::UNAUTHORIZED).into_response()
            }
        });
    let routes = routes.or(login);
Enter fullscreen mode Exit fullscreen mode

Use cookie for Authorization

To authorize request, we need to implement a filter in Warp, and use it like this, here we use Filter::untuple_one to unroll nested tuple layers from extractions.

  let verify = warp::path!("api" / "verify")
        .and(warp::get())
        .and(auth_validation())
        .untuple_one()
        .map(|| warp::reply::reply().into_response());
    let routes = routes.or(verify);
Enter fullscreen mode Exit fullscreen mode

And the auth_validation will call another built-in filter warp::cookie to extract the token from request header:

struct Unauthorized;

impl reject::Reject for Unauthorized {}

fn auth_validation() -> impl Filter<Extract = ((),), Error = Rejection> + Copy {
    warp::cookie::<String>("token").and_then(|token: String| async move {
        println!("token: {}", token);
        if let Some(true) = auth::verify_token(&token) {
            Ok(())
        } else {
            Err(warp::reject::custom(Unauthorized))
        }
    })
}

Enter fullscreen mode Exit fullscreen mode

Some thoughts

Even I have spent some time writing code in Rust, I still need to learn some new concepts or some details in a Web framework such as Warp. From my experience, there are some unnatural part for users who used to some other programming languages. For example, the return type of a filter:

impl Filter<Extract = ((),), Error = Rejection> + Copy
Enter fullscreen mode Exit fullscreen mode

It's just not so easy to say what this mean? And why we need to call untuple_one with the filter?

I know we must obey the rules of type system, and we need to add more annotations when writing Rust code, it's just not so easy for learning as other programming languages.

Even so, I'm still having fun with it for it bringing some new things for programming.

warp Article's
29 articles in total
Favicon
Warp AI Terminal: A Beginner’s Guide to the Future of Command Line Interfaces
Favicon
OSX Sequoia & Operation not permitted (os error 1)
Favicon
iTerm on steroids: Why I've Switched to Warp
Favicon
warp adoption guide: Overview, examples, and alternatives
Favicon
Warp terminal on WSL is AMAZING
Favicon
How to use Cloudflare Warp as a socks proxy on your local computer
Favicon
Dank Owl - custom themes in Warp terminal and neovim
Favicon
Reasons to change the default terminal to Warp
Favicon
How Warp Works
Favicon
The terminal is on life support. Is it worth saving?
Favicon
How we designed themes for the terminal - a peek into our process
Favicon
Warp’s product principles for reinventing the terminal
Favicon
How to hire engineers at an early stage startup
Favicon
Code-first vs. Product-first
Favicon
The Biggest Mistake I See Engineers Make
Favicon
Multiply by 𝝅
Favicon
Coding
Favicon
Planning
Favicon
Host Interns
Favicon
ทำไมเรายังไม่ Warp (terminal)
Favicon
Rust Warp: Use Cookie for Authorization
Favicon
REST API with Rust + Warp 1: Introduction
Favicon
REST API with Rust + Warp 3: GET
Favicon
REST API with Rust + Warp 2: POST
Favicon
REST API with Rust + Warp 4: PUT & DELETE
Favicon
REST API with Rust + Warp 5: Beyond test utilities
Favicon
Validating JSON input in Rust web services
Favicon
Dotnet Warp to further optimize .Net self-contained single executable file.
Favicon
My First Rust Web Service (And Other Firsts)

Featured ones: