Currently, in my SvelteKit Web Application, I'm using Appwrite as my DB and Authentication/User management backend. I'm using Discord OAuth with Appwrite to log the user in. Since I'm using OAuth, I can't follow this Appwrite SSR Auth with Svelte: https://github.com/Meldiron/appwrite-svelte-ssr because my server does not see the set-cookies headers, which contain the auth secret. As a result, I've had to come up with a workaround. As seen in the diagram attached, I end up making the client create a JWT which the server can use for SSR (very simplified). There are a few issues with this though:
- The JWT lasts for 15 minutes and then it expires due because of the way Appwrite works (https://appwrite.io/docs/references/cloud/client-web/account#createJWT)
- After 15 minutes, the client will still be logged in since it has the cookies from Appwrite, but the server will not because the JWT will have expired resulting in pretty bad desync
- When using the JWT on the server, there is no session linked (I can't use
#getSession('current');
), forcing me to add a Session Id cookie in order to get session info
These issues mean that my app is slower and users are limited to a ~15 minute session (because I don't want desync). In an ideal world, the cookie that Appwrite sets on the client (with the auth secret) would also be available to the server so that it can authenticate with the same thing. I'd like to know if there is a better way to do authentication with Appwrite, SvelteKit, and Discord OAuth. Or, if there is a way to not limit users to a 15 minute session. Also, I am aware of the third-party cookies stuff (https://appwrite.io/docs/advanced/platform/custom-domains#third-party-cookies), but I don't think that the solutions offered there would help in this case.
I may be wrong in some of my assumptions, so please correct me. If you could offer any help, it would be much appreciated!
Sorry, in my diagram between the 2nd and 3rd step the client is redirected to Appwrites OAuth route, which then redirects to Discord's OAuth Gateway. This, though, does not really affect anything else I mentioned or have issues with.
@Engineous we are currently working on a solution to improve the SSR framework experience with OAuth https://github.com/appwrite/appwrite/pull/5777
I can try helping further but I might need a little more clarity on how exactly your server function is being called and how the interaction takes place, to figure out a workaround to the JWT expiration limit
Can you share your project repository by any chance?
Unfortunately, I'm not allowed to share the repo at this time. But I can share some snippets of code:
+page.ts
load function
let id: string;
let jwt: string;
const sessionPromise = appwrite.account.getSession('current').then((result) => {
id = result?.$id;
if (id) console.log('Got session id');
else throw new Error('Failed to get session');
});
const jwtPromise = appwrite.account.createJWT().then((result) => {
jwt = result?.jwt;
if (jwt) console.log('Created JWT');
else throw new Error('Failed to create JWT');
});
// Running in parallel so it's faster
await Promise.all([sessionPromise, jwtPromise]);
const response = await fetch(url.href, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify({ jwt, id })
});
console.log('3');
return;
+page.server.ts
post endpoint
export const POST: RequestHandler = async ({ cookies, request }) => {
const { jwt, id } = await request.json();
const account = new Account(appwrite.client.setJWT(jwt));
const session = await account.getSession(id);
if (session?.$id !== id) throw new Error('Invalid session');
// Set cookie to expire in 15 minutes, since the JWT will anyways
cookies.set('jwt', jwt, {
expires: new Date(
Date.now() + 15 * 60 * 1000
),
path: '/',
secure: true,
sameSite: 'lax'
});
cookies.set('id', id, {
expires: new Date(
Date.now() + 15 * 60 * 1000
),
path: '/',
secure: true,
sameSite: 'lax'
});
return new Response();
};
Also, thanks for making me aware of that PR; when would you estimate it to be accepted and merged?
The timeline is expected in the very near future
One hack I can suggest is creating a new JWT everytime you need to create a POST request. This does increase the overhead for each request but it would prevent the 15 minute lifetime of the JWT from interfering with your functionality
Recommended threads
- How to Avoid Double Requests in function...
I'm currently using Appwrite's `functions.createExecution` in my project. I want to avoid double requests when multiple actions (like searching or pagination) a...
- Send Email Verification With REST
I am using REST to create a user on the server side after receiving form data from the client. After the account is successfully created i wanted to send the v...
- Use different email hosts for different ...
Hello, I have 2 projects and i want to be able to set up email templates in the projects. Both projects will have different email host configurations. I see ...