Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(utils/sessions): improve docs #7247

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

aaronadamsCA
Copy link
Contributor

See #7225 (comment) for details. In the absence of a larger rewrite I think this should substantially improve clarity and reduce confusion.

Key bits include:

  • Clarifying that regardless of your session storage strategy, if you don't commitSession(), you're losing your changes.
  • Further clarifying that if you are using cookie session storage and you don't Set-Cookie, you're still losing your changes.
  • Correcting the cookie size limit. It's actually 1024 bytes for a single cookie value in Chromium and Firefox (sources: RFC 6265, Chrome Platform Status). 4 KB is the limit for all cookie names + values combined.
  • Consistently recommending app/session.server.ts over app/session.ts.

The one more opinionated thing I did as well was to remove the lengthy example under session.flash(), because there is already an example of the same thing earlier in the doc.

Please let me know if there's anything else I can do to help ship this, so that I can stop making the same mistakes over and over every time I read this doc page. Thanks!

@brophdawg11

@changeset-bot
Copy link

changeset-bot bot commented Aug 24, 2023

⚠️ No Changeset found

Latest commit: 4c3b02a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@MichaelDeBoey MichaelDeBoey changed the title docs: Correct and improve Sessions docs docs(utils/sessions): improve docs Aug 25, 2023
docs/utils/sessions.md Outdated Show resolved Hide resolved
docs/utils/sessions.md Show resolved Hide resolved
@remix-cla-bot
Copy link
Contributor

remix-cla-bot bot commented Aug 25, 2023

Thank you for signing the Contributor License Agreement. Let's get this merged! 🥳

@brophdawg11 brophdawg11 added the feat:sessions Sessions related issues label Aug 25, 2023
The downside is that you have to `commitSession` in almost every loader and action. If your loader or action changes the session at all, it must be committed. That means if you `session.flash` in an action, and then `session.get` in another, you must commit it for that flashed message to go away. With other session storage strategies you only have to commit it when it's created (the browser cookie doesn't need to change because it doesn't store the session data, just the key to find it elsewhere).
However, cookie-based sessions may not exceed the browser's cookie size limit, typically 1024 bytes per cookie value (and 4 KB total for all cookies).

The other downside is that you need to update the `Set-Cookie` header in every loader and action that modifies the session. With other strategies you only need to set the session cookie once, because it doesn't actually store any session data, just the key to find it elsewhere.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That means if you session.flash in an action, and then session.get in another, you must commit it for that flashed message to go away.

^ Did we lose this nuance from above? This feels important to call out explicitly since get is not an obvious mutation (even though I know we have a flash section below).

Suggested change
The other downside is that you need to update the `Set-Cookie` header in every loader and action that modifies the session. With other strategies you only need to set the session cookie once, because it doesn't actually store any session data, just the key to find it elsewhere.
The other downside is that you need to update the `Set-Cookie` header in every loader and action that modifies the session (this includes reading a flashed session value). With other strategies you only need to set the session cookie once, because it doesn't actually store any session data, just the key to find it elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made this change.


The downside is that you have to `commitSession` in almost every loader and action. If your loader or action changes the session at all, it must be committed. That means if you `session.flash` in an action, and then `session.get` in another, you must commit it for that flashed message to go away. With other session storage strategies you only have to commit it when it's created (the browser cookie doesn't need to change because it doesn't store the session data, just the key to find it elsewhere).
However, cookie-based sessions may not exceed the browser's cookie size limit, typically 1024 bytes per cookie value (and 4 KB total for all cookies).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original 4k is accurate here. It's 4k per total cookie length (including name/attrs) and 1k per attribute value per Chrome's docs and the spec also states 4k but doesn't say anything about the attribute length limit.

I did a quick test and as expected this is the largest cookie I can set before it gets ignored:

"Set-Cookie": `test=${new Array(4092).fill("a").join("")}`,
Screenshot 2023-08-25 at 10 05 46 AM

Let's just leave it at 4k and not say anything about the 1k attribute limit.

The only "combined" cookie limits I've run into is ~15k in GCP before you start getting 429 errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
However, cookie-based sessions may not exceed the browser's cookie size limit, typically 1024 bytes per cookie value (and 4 KB total for all cookies).
However, cookie-based sessions may not exceed the browser's cookie size limit - typically 4k bytes per cookie.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I've made this change too, with an extra detail I did not know before:

However, cookie-based sessions may not exceed browser cookie size limits of 4k bytes. If your cookie size exceeds this limit, commitSession() will throw an error.

This is good to call out, since it clarifies that exceeding the limit will result in an app crash. I was happy to see this safeguard present in the library—better to log an app crash than to have a page rejected by a browser.

https://github.com/remix-run/remix/blame/025ecac479def75dad3db4869ea1b4fb8917df2e/packages/remix-server-runtime/sessions/cookieStorage.ts#L53-L58


For file-backed sessions, use `createFileSessionStorage()`. File session storage requires a file system, but this should be readily available on most cloud providers that run express, maybe with some extra configuration.

The advantage of file-backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a regular file on disk, ideal for sessions with more than 4kb of data.
The advantage of file-backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a regular file on disk, ideal for sessions with more than 1024 bytes of data.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The advantage of file-backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a regular file on disk, ideal for sessions with more than 1024 bytes of data.
The advantage of file-backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a regular file on disk, ideal for sessions with more than 4k bytes of data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@MichaelDeBoey MichaelDeBoey added needs-response We need a response from the original author about this issue/PR and removed needs-response We need a response from the original author about this issue/PR labels Oct 31, 2023
@MichaelDeBoey
Copy link
Member

@aaronadamsCA Are you still interested in getting this PR merged?
If so, could you please rebase onto latest main & resolve conflicts?

@MichaelDeBoey MichaelDeBoey added the needs-response We need a response from the original author about this issue/PR label Oct 31, 2023
@aaronadamsCA
Copy link
Contributor Author

Whoops, thanks for the bump, @MichaelDeBoey! I completely forgot about this.

I've updated the branch and made @brophdawg11's requested changes. The only thing that needs checking is the line numbers in the code block, I'm not sure how to preview those to ensure the correct lines are being highlighted.

@github-actions github-actions bot removed the needs-response We need a response from the original author about this issue/PR label Nov 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed docs feat:sessions Sessions related issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants