Search code examples
firefoxrustcookiesbackendactix-web

How to send a cookie in Actix-Web for Any version of Firefox


I am currently building a web server with authentication. The problem is that I can't setup cookie creation (despite the fact that my browser receives the information correctly).

My code

use actix_web::{get, post, App, HttpServer, Responder, HttpRequest, HttpResponse};

use actix_web::cookie::{Cookie, SameSite};


#[get("/login")]
async fn send_cookie(req: HttpRequest) -> impl Responder {

   //Print cookie token //For know if precedent try work 
    match req.cookie("token") {
        Some(value) => println!("{}", value.value()),
        None => println!("No token"),  
    };
    let c = Cookie::build("token", "jfpzihnfiobjgnopka")
        .domain("localhost")
        .path("/login")
        .http_only(true)
    .finish();

    // Return the cookie to the user
    HttpResponse::Ok()
        .cookie(c)
        .finish()
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

    HttpServer::new(move || {
        App::new()
            .service(send_cookie)
    })
    .bind(("localhost", 8080))?
    .run()
    .await
}

My header when i'm connect to http://localhost:8080/login

HTTP/1.1 200 OK
content-length: 0
set-cookie: token=jfpzihnfiobjgnopka; HttpOnly; Path=/login; Domain=localhost
date: Mon, 02 Oct 2023 06:57:56 GMT

I tested a lot of different things, having a local domain other than localhost, a url for try it if localhost didn't work, tested several cookie parameters, build the cookie directly in the HttpResponse, but nothing made the cookie never get created.

UPDATE

This code work in Edge, but not in Firefox Nightly (or all version of Firefox i have just tested). What i need modify for it's work in Firefox ? (and, probably, other navigator)


Solution

  • Okay after MORE testing i find why it's doesn't work. I'm going to document why it didn't work and it's a mistake on my part and can be summed up in one sentence: using the firefox request console is a really bad idea.

    I simplified my code to be clear and show my problem. It may have been my mistake to truncate the function. In reality, it looks more like this :

    async fn send_cookie(req: HttpRequest) -> impl Responder {
    
        let user = match head.get("user") {
            Some(value) => value,
            None => return HttpResponse::BadRequest().body("No user"),  
        };
        let password = match head.get("password") {
            Some(value) => value,
            None => return HttpResponse::BadRequest().body("No password"),  
        };
    
        // Hash the password and convert it to hex string
        let password = hasher(password.to_str().unwrap(), "salt");
        let password = to_hex_string(password);
    
        // Connect to the database
        let db = database::open_database();
        // Verify if the user exist in the database
        match database::verify_user(&db, user.to_str().unwrap()) {
            true => println!("User exist"),
            false => return HttpResponse::BadRequest().body("User doesn't exist"),
        };
    
        // Verify if the password is correct
        match database::verify_password(&db, user.to_str().unwrap(), &password) {
            true => println!("Password correct"),
            false => return HttpResponse::Unauthorized().body("Password incorrect"),
        };
    
       //Print cookie token //For know if precedent try work 
        match req.cookie("token") {
            Some(value) => println!("{}", value.value()),
            None => println!("No token"),  
        };
        let c = Cookie::build("token", "jfpzihnfiobjgnopka")
            .domain("localhost")
            .path("/login")
            .http_only(true)
        .finish();
    
        // Return the cookie to the user
        HttpResponse::Ok()
            .cookie(c)
            .finish()
    }
    

    For my test, I went through the firefox request console like this :

    Image of Firefox Request Console

    And... I've just tested it without going through this damned console (by disabling the whole connection step and reloading the page) and... it's works... The request console save nothing.

    Hopefully it can help people just in case, sorry for the inconvenience! And thanks so much for helper.