Home > Blockchain >  cookies getting deleted after automatic redirect
cookies getting deleted after automatic redirect

Time:06-10

I have a log-in page which makes a request to my server, which sets a session cookie and redirects to a dashboard page. On the log-in page, I can verify the cookie gets set correctly after sending credentials, and it will persist when I manually click on links to navigate around the site (as expected).

However, when I try to automatically redirect to the dashboard after the log-in function succeeds, my cookie is unset and I cannot figure out where it has gone. I have tried managing the redirect via document.location/window.location with the different .href/.path/.url fields, but the cookie is gone after calling any of those or refreshing the page.

I'm using self-signed HTTPS 127.0.0.1 with CORS (I am no longer receiving CORS errors after lots of headache, so I don't think the problem is there, especially since I can see it exists without the redirect). Also, I'm using Svelte as the front-end and Axum (Rust) as my back-end, if that's important at all.

Why does my cookie get "eaten" when trying to force-redirect the user to another page?

request method:

await fetch('https://localhost:4000/users', {
    method: 'POST',
    credentials: 'include',
    headers: {
        'Content-Type': 'application/json;charset=utf-8'
    },
    body: `{ "email": "${email}", "password": "${await hash}" }`
});

// cookie exists if this line is removed
document.location.href = '/dashboard';
// cookie is gone when the new page loads

server config (Axum):

let server = axum_server::bind_rustls(
    SocketAddr::from(([127, 0, 0, 1], 4000)),
    tls_config,
)
.serve(
    Router::new()
        .route("/", get(root))
        .layer(
            CorsLayer::new()
                .allow_headers([
                    header::CONTENT_TYPE,
                    header::CONTENT_LENGTH,
                    header::COOKIE,
                    header::SET_COOKIE,
                ])
                .allow_methods([
                    Method::GET,
                    Method::HEAD,
                    Method::OPTIONS,
                    Method::DELETE,
                    Method::POST,
                ])
                .allow_origin([
                    HeaderValue::from_str("http://127.0.0.1:3000").unwrap(),
                    HeaderValue::from_str("https://127.0.0.1:3000").unwrap(),
                ])
                .allow_credentials(true),
        )
        .into_make_service(),
);

response headers:

HTTP/2 200 OK
content-type: application/json
set-cookie: session=1234; Path=/; HttpOnly; SameSite=None; Secure
content-length: 26
access-control-allow-origin: https://127.0.0.1:3000
access-control-allow-credentials: true
vary: origin
vary: access-control-request-method
vary: access-control-request-headers
date: Tue, 07 Jun 2022 01:56:11 GMT

CodePudding user response:

I ended up replacing my fetch calls with axios calls and it works as expected now. I still don't know if I was using it wrong, but these look like they'd be pretty identical to me...

await fetch('https://localhost:4000/users', {
    method: 'POST',
    credentials: 'include',
    headers: {
        'Content-Type': 'application/json;charset=utf-8'
    },
    body: `{ "email": "${email}", "password": "${await hash}" }`
});
await axios.post('https://localhost:4000/users', {
    email: email,
    password: await hash,
}, {
    withCredentials: true
});

If somebody is able to explain what the difference is, I'd be super interested :)

  • Related