rwf2 / Rocket

A web framework for Rust.
https://rocket.rs
Other
24.55k stars 1.57k forks source link

Cookies aren't read by get methods but it exists in the browser #2721

Closed Ragudos closed 9 months ago

Ragudos commented 9 months ago

Rocket Version

0.5.0

Operating System

Windows 10 Pro v.21H1 64-bit OS build: 19043.1826

Rust Toolchain Version

1.75.0

What happened?

I have a simple web server with my own login functionality. It adds a private cookie once the credentials match what the database has. I am at the beginning stages of this project, so I restart the server every time I make a change since I have not enabled hot reload yet. However, after reloading, it seems that the get methods are not reading the cookie. I printed the contents of the request and it's there as well as in the browser.

Test Case

I cannot find a way to add form data to the request in a test function yet. Instead, I show the log when I hit an endpoint.

Log Output

>  Compiling chat_server v0.1.0 (C:\Personal\projects\rust\chat_server)
    Finished dev [unoptimized + debuginfo] target(s) in 9.18s
     Running `target\debug\chat_server.exe`
relation "_sqlx_migrations" already exists, skipping
Configured for debug.
   >> address: 127.0.0.1
   >> port: 8000
   >> workers: 4
   >> max blocking threads: 512
   >> ident: Rocket
   >> IP header: X-Real-IP
   >> limits: bytes = 8KiB, data-form = 2MiB, file = 1MiB, form = 32KiB, json = 1MiB, msgpack = 1MiB, string = 8KiB
   >> temp dir: C:\Users\ANGELR~1\AppData\Local\Temp\
   >> http/2: true
   >> keep-alive: 5s
   >> tls: disabled
   >> shutdown: ctrlc = true, force = true, grace = 2s, mercy = 3s
   >> log level: normal
   >> cli colors: true
   >> secret key: [generated]
Warning: secrets enabled without a stable `secret_key`
   >> disable `secrets` feature or configure a `secret_key`
   >> this becomes an error in non-debug profiles
Routes:
   >> (homepage) GET /
   >> (FileServer: assets) GET /assets/<path..> [10]
   >> (index) GET /session/
   >> (unauthorized) GET /session/ [2]
   >> (login) GET /session/login
   >> (login_page) GET /session/login [2]
   >> (post_login) POST /session/login
   >> (register) GET /session/register
   >> (register_page) GET /session/register [2]
   >> (post_register) POST /session/register
Fairings:
   >> Database startup (ignite)
   >> Database migration (ignite)
   >> 'sqlx' Database Pool (ignite, shutdown)
   >> Shield (liftoff, response, singleton)
   >> Templating (ignite, liftoff, request)
Shield:
   >> X-Content-Type-Options: nosniff
   >> X-Frame-Options: SAMEORIGIN
   >> Permissions-Policy: interest-cohort=()
Templating:
   >> directory: templates
   >> engines: ["hbs"]
Rocket has launched from http://127.0.0.1:8000
GET / text/html:
   >> Matched: (homepage) GET /
CookieJar { original: CookieJar { original_cookies: {DeltaCookie { cookie: Cookie { cookie_string: Some("user_info=VH95BXfoswHQ+PPfxhDrOq2C8XCJX6v8QQjKhF3St74oYk2fvyxDG7UpF4ARPcNi34r6p7Ns6DQMBOzTJhK3wSUyF0iW6QSjZXJZf93SGpqucIywh6BqOY8JcIfAfu0mYmrud0OL98o9bleUs+RlVdqD5tOOu8kGaMB0UiFFBJHrLwPbaZvFgAm9eSN4apMMrA9GzkVi"), name: Indexed(0, 9), value: Indexed(10, 210), expires: None, max_age: None, domain: None, path: None, secure: None, http_only: None, same_site: None }, removed: false }}, delta_cookies: {} }, pending: [] }
   >> Outcome: Success(200 OK)
   >> Response succeeded.
GET /assets/globals.css text/css:
   >> Matched: (FileServer: assets) GET /assets/<path..> [10]
   >> Outcome: Success(200 OK)
GET /assets/htmx.min.js:
   >> Matched: (FileServer: assets) GET /assets/<path..> [10]
   >> Outcome: Success(200 OK)
   >> Response succeeded.
GET /assets/htmx-loading.min.js:
   >> Matched: (FileServer: assets) GET /assets/<path..> [10]
   >> Response succeeded.
   >> Outcome: Success(200 OK)
   >> Response succeeded.

Additional Context

I do not know if it is an intended behavior (maybe there is a memory storage of cookies and that is why it is gone on server restart?). I am new to Rust and Rocket, so pardon me if this Issue is not of importance. Thank you.

Here's the main rs file:

image

and the forwarding to see if a user exists when an endpoint requires it as a parameter:

image

Steps to reproduce (since Idk how to test):

  1. Make an endpoint for logging in and a simple database interaction (maybe just have file-based storage for simplicity's sake):
  2. Make that endpoint redirect you somewhere which requires you to be logged in (else, it redirects you to the login endpoint).
  3. Now, once there, close the server and start it up again. NOTE: Do not delete the cookie on the Application panel in your browser.
  4. Refresh the page.

You'll see that you'll get redirected and the return type of the get methods are None, but the cookie exists when it's printed out.

Additionally, other cookies (added on the browser) gets read successfully. For example. theme cookie with the key of "theme" gets read properly even after server restart.

image

System Checks

DavidSkrundz commented 9 months ago

I believe the issue is you don't have a secret key configured, so when restarting the server a new key is generated, which causes decryption to fail on your old cookies.

You are using .get_private() and the logs show:

   >> secret key: [generated]
Warning: secrets enabled without a stable `secret_key`
   >> disable `secrets` feature or configure a `secret_key`
   >> this becomes an error in non-debug profiles

The solution would be to specify a key in your Rocket.toml. I use openssl rand -base64 32 to generate my keys, I'm not sure if that works on windows.

[default]
secret_key = "MnNHJCt69yU7xdyCiExtT1vto6geQ6Xd2VDpaD9AZx0="
Ragudos commented 9 months ago

Oh, I see! I thought the warning about secrets was related to the .env variables. I'll try it out and close this issue. Thank you!