question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I am currently exploring Pocketbase using their Pocketbase Js with Remix Js. The problem is that I can’t adapt the operation of AuthStore with each request to the server.

Suggestion: To solve the drawback can an additional parameter to set the token manually.

pocketbaseClient.Users.getOne('idUser', {}, 'User eyJh...')

[Original] Compatibilidad con SSR

Actualmente estoy explorando Pocketbase usando su Pocketbase Js con Remix Js. El problema es que no puedo adaptar el funcionamiento de AuthStore con cada petición al servidor.

Sugerencia: Para solucionar el inconveniente pueden un parámetro adicional para poner el token manualmente

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:24 (15 by maintainers)

github_iconTop GitHub Comments

2reactions
ganigeorgievcommented, Aug 24, 2022

I’ve explored the available options the last couple of days, but I couldn’t find a “one size fit all” solution, so I’ve implemented the following in the latest v0.6.0 SDK release:

  • I’ve added 2 cookie helper methods to the BaseAuthStore to simplify working with cookies:

    // update the store with the parsed data from the cookie string
    client.authStore.loadFromCookie('pb_auth=...');
    
    // exports the store data as cookie, with option to extend the default SameSite, Secure, HttpOnly, Path and Expires attributes
    client.authStore.exportToCookie({ httpOnly: false }); // Output: 'pb_auth=...'
    

    The exported cookie uses the token expiration date and also truncate the user model to its minimum (id, email, [verified]) in case it exceed 4096 bytes (this should be a very rare case).

  • I’ve added some examples for SvelteKit (based on @ollema suggestion), Nuxt 3 and Next.js in https://github.com/pocketbase/js-sdk#ssr-integration.

The above should help (or at least to give you some idea) how to deal with SSR, but if someone still have difficulties making it work, feel free to let me know and I’ll try to provide some guidance based on your use case.

2reactions
ollemacommented, Aug 21, 2022

@ganigeorgiev figured I would give an update on the AuthStore situation with SvelteKit SSR.

After doing some research it seems like this is the most “idiomatic” approach (for now, SvelteKit is still not 1.0 so things could change!):


Like you suggested you would use a new client instance for each request/response.

In SvelteKit, this could be handled in the handle function in hooks.ts.

src/hooks.ts

import type { Handle } from '@sveltejs/kit';
import PocketBase, { User } from 'pocketbase';
import cookie from 'cookie';

export const handle: Handle = async ({ event, resolve }) => {
	const client = new PocketBase('http://127.0.0.1:8090');
	event.locals.pocketbase = client;

	const { token, user } = cookie.parse(event.request.headers.get('Cookie') ?? '');

	if (!token || !user) {
		return await resolve(event);
	}

	client.authStore.save(token, new User(JSON.parse(user)));
	if (client.authStore.isValid) {
		event.locals.user = client.authStore.model as User;
	}

	return await resolve(event);
};

By setting event.locals.pocketbase to client, the client will be available in handlers in +server.ts and server-only load functions (handle docs)

In the handle function above, I have also populated event.locals.user with the current user if the token is valid.


Now, while the handle function above can be used to access the client and/or the current user in SSR, how do we authenticate a user or in other words store the token and (user)model?

If I understood it correctly, you would create server endpoints for this, for example: src/routes/auth/signin/+server.ts

import type { RequestHandler } from '@sveltejs/kit';
import cookie from 'cookie';

const defaultCookieOptions = { maxAge: 30 * 24 * 60 * 60, path: '/', httpOnly: true, sameSite: true, secure: true };

export const POST: RequestHandler = async ({ request, locals }) => {
	const response = new Response('{}');

	const { email, password } = await request.json();
	try {
		const { token, user } = await locals.pocketbase.users.authViaEmail(email, password);
		locals.pocketbase.authStore.save(token, user);
		locals.user = user;
		response.headers.append('Set-Cookie', cookie.serialize('token', token, defaultCookieOptions));
		response.headers.append('Set-Cookie', cookie.serialize('user', JSON.stringify(user), defaultCookieOptions));
	} catch {}

	return response;
};

and src/routes/auth/signout/+server.ts

import type { RequestHandler } from '@sveltejs/kit';
import cookie from 'cookie';

const defaultCookieOptions = { maxAge: -1, path: '/', httpOnly: true, sameSite: true, secure: true };

export const POST: RequestHandler = async ({ locals }) => {
	const response = new Response('{}');

	locals.pocketbase.authStore.clear();
	locals.user = undefined;
	response.headers.append('Set-Cookie', cookie.serialize('token', '', defaultCookieOptions));
	response.headers.append('Set-Cookie', cookie.serialize('user', '', defaultCookieOptions));

	return response;
};

It should be noted that the snippets above do not have any error handling, they can just be seen as inspiration.

To update the profile of the currently logged in user, you could add an additional /auth/save route for example.


Final thoughts

  • For PocketBase + SvelteKit SSR, the default AuthStore can be used today with the help of hooks.ts and some server endpoints
  • With that said, any official SSR AuthStore that could simplify the method above would be very nice!
  • If no official AuthStore for SSR will be added - then maybe (a revised) version of this method (and similar versions for other frameworks) could be added to the docs?
  • I am not experienced with either JS, Svelte, SvelteKit or PocketBase, so take this with a grain of salt 😅
Read more comments on GitHub >

github_iconTop Results From Across the Web

Server-Side Rendering - Vite
Vite provides built-in support for server-side rendering (SSR). The Vite playground contains example SSR setups for Vue 3 and React, which can be...
Read more >
SSR Support for AWS Amplify JavaScript Libraries
Enabling Server-Side Rendering (SSR) support in an Amplify app. When using the Amplify CLI, the aws-exports.js file gets created and updated ...
Read more >
Server-Side Rendering (SSR) - Vue.js
Vite SSR # ... Vite provides built-in support for Vue server-side rendering, but it is intentionally low-level. If you wish to go directly...
Read more >
Superior Support Resources Inc.
SSR's experts can resolve issues from password resets and software questions to equipment failure and device configuration.
Read more >
Using Server-side Rendering (SSR) - Gatsby
Introduction Server-side Rendering (SSR) is one of Gatsby's rendering options and allows you to pre-render a page with data that is…
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found