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)
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.