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

Sessions #1050

Open
ascorbic opened this issue Nov 2, 2024 · 0 comments
Open

Sessions #1050

ascorbic opened this issue Nov 2, 2024 · 0 comments

Comments

@ascorbic
Copy link
Contributor

ascorbic commented Nov 2, 2024

Summary

A first class Astro.session primitive, with pluggable storage backends. Inspired by PHP sessions and Rails sessions, this will allow on-demand rendered pages and API endpoints to use a new Astro.session object to access arbitrary data, scoped to that browser session. A session ID cookie is used to associate the browser with the session, but the actual data is stored on the backend.

Background and motivation

HTTP is a stateless protocol, so sharing data between requests is a problem that most server-rendered web apps need to solve. The standard way is using cookies, but these have limitations. Firstly, they are limited to 4kB in size, so can't be used for anything complex. The full data also needs to be sent along with every request and response, increasing their size. Finally, even when encrypted they can be vulnerable to replay attacks. We have encountered the limitations of cookie storage when building Astro Actions, where we need response data to persist between page redirects. It is easy to reach the 4kB limit in these cases.

For this reasons, most non-trivial apps need to implement some kind of server-side session handling. In most cases these work by storing a random session id in a cookie, and using that to retrieve the full session data on the server. Monolithic frameworks such as Rails and Laravel normally implement sessions at the framework or server level, and PHP has built-in session handling which heavily influenced this proposal. However it isn't a common primitive for modern JS frameworks, in part due to the fact that these need to work in serverless environments, so simple default backends such as filesystem storage cannot be relied upon. We propose addressing this by allowing adapters to provide default implementations, relying on the primitives that they have available.

Goals

  • Simple key/value API, similar to Astro.cookies (Astro.session.get(), Astro.session.set())
  • Additional control over the session via methods such as Astro.session.regenerateId() and Astro.session.destroy()
  • Storage drivers for popular providers available out of the box via a third party library such as unstorage, and the ability to use custom drivers.
  • Adapters can specify a default storage driver, with Node using filesystem storage by default.
  • Other settings such as cookie name, session expiry etc are also optionally configurable.
  • Sessions are lazy-loaded and auto-generated when first accessed. Session ID cookie is get and set automatically.

Non-goals

  • User management, auth etc. This is just raw sessions, but they may be useful if someone is implementing auth
  • Building or maintaining our own drivers

Example

---
let cart = Astro.session.get('cart')
if (!cart) {
	cart = createNewCart()
	Astro.session.set('cart', cart)
}
---

<div>{cart.items.length} items</div>
// astro.config.ts
import { defineConfig } from "astro/config"

export default defineConfig({
  output: "server",
  adapter: nodejs({
    mode: 'standalone',
  }),
  session: {
    storage: {
      driver: 'planetscale',
      config: {
      	url: process.env.PLANETSCALE_URL
    	}
    }
  }
})
  

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Stage 2: Accepted Proposals, No RFC
Development

No branches or pull requests

1 participant