svelte-kit-cookie-session
svelte-kit-cookie-session copied to clipboard
Synchronize sessions (Server -> Client)
This PR implements syncing sessions between the server and client.
You'll have to set the session store yourself, but this can be easily done.
This works best with the enhance
action from kit
!
/// lib/form.ts
import { session } from "$app/stores";
export function enhance(){
...
async function handle_submit(e) {
...
if (response.ok) {
if (response.headers.has('x-svelte-kit-cookie-session-needs-sync')) {
const sessionData = await fetch('/__session.json').then((r) => (r.ok ? r.json() : null));
if (sessionData) {
session.set(sessionData);
}
}
...
}
...
}
}
The cast to any
is a little unfortunate but it's something I'd be willing to add by hand if there was no other option - maybe some documentation for the signature is enough for now?
edit: Spoke too soon :( my session store does not seem to be getting the new value when i call sync
. I trimmed down my example so now I have a function that logs my users in that looks roughly like the following. After navigating to /routeA
, my session does not contain the new data.
export async function authorizeUser(variables: {}) {
// trigger the mutation to authorize the user
var sessionData = await logIn({ variables })
// update the session with the result
await fetch('/auth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(sessionData)
})
await (session as any).sync()
goto('/routeA')
}
Here's the endpoint:
export async function POST({ request, locals }) {
// save the tokens in the local session
locals.session.set(await request.json())
return {}
}
The cast to
any
is a little unfortunate but it's something I'd be willing to add by hand if there was no other option - maybe some documentation for the signature is enough for now?edit: Spoke too soon :( my session store does not seem to be getting the new value when i call
sync
. I trimmed down my example so now I have a function that logs my users in that looks roughly like the following. After navigating to/routeA
, my session does not contain the new data.export async function authorizeUser(variables: {}) { // trigger the mutation to authorize the user var sessionData = await logIn({ variables }) // update the session with the result await fetch('/auth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(sessionData) }) await (session as any).sync() goto('/routeA') }
Here's the endpoint:
export async function POST({ request, locals }) { // save the tokens in the local session locals.session.set(await request.json()) return {} }
Oh no! Can you see a request to /__session.json when calling sync or have some kind of error in the console?
Ahh i think you have to await locals.session.set() in your endpoint! Since switching to webcrypto those methods are async.
Oh yep! That was it 👍
I am now running into a new error when calling session.sync()
: Cannot set session store before subscribing
. I haven't been able to dig into it much yet but i figured I would share while I do that in case you have any ideas
You'll have to use the session store somewhere in your application via $session
. This error would also appear if you'd use the unmodified version and session.set
or session.update
. The set and update methods are getting available after the first subscription. Don't know the exact reason behind it.