fix: more ssr inconsistencies

This commit is contained in:
loks0n
2024-03-09 19:13:02 +01:00
parent 1d15978eaa
commit 847a4cb0c1
18 changed files with 111 additions and 103 deletions

View File

@@ -4,7 +4,8 @@ title: Initialize SDK
description: Add authentication to a SvelteKit project using Appwrite.
step: 3
---
Before you can use Appwrite, you need to create the Appwrite `Client` and set the project ID and endpoint.
Before you can use Appwrite, you need to create the Appwrite `Client` and set the project ID and endpoint.
The client is then used to create services like `Databases` and `Account`, so they all point to the same Appwrite project.
Create a function to build services you need in a file like `src/lib/server/appwrite.js` and **exporting the instances**.
@@ -21,14 +22,14 @@ Doing so could create security vulnerabilities.
// src/lib/server/appwrite.js
import { Client, Account } from 'node-appwrite';
import { APPWRITE_KEY } from '$env/static/private';
import { PUBLIC_APPWRITE_ENDPOINT, PUBLIC_APPWRITE_PROJECT_ID } from '$env/static/public';
import { PUBLIC_APPWRITE_ENDPOINT, PUBLIC_APPWRITE_PROJECT } from '$env/static/public';
export const SESSION_COOKIE = 'my-custom-session';
export function createAdminClient() {
const client = new Client()
.setEndpoint(PUBLIC_APPWRITE_ENDPOINT)
.setProject(PUBLIC_APPWRITE_PROJECT_ID)
.setProject(PUBLIC_APPWRITE_PROJECT)
.setKey(APPWRITE_KEY); // Set the Appwrite API key!
// Return the services we want to use.
@@ -42,11 +43,15 @@ export function createAdminClient() {
export function createSessionClient(event) {
const client = new Client()
.setEndpoint(PUBLIC_APPWRITE_ENDPOINT)
.setProject(PUBLIC_APPWRITE_PROJECT_ID);
.setProject(PUBLIC_APPWRITE_PROJECT);
// Extract our custom domain's session cookie from the request
const session = event.cookies.get(SESSION_COOKIE);
if (session) client.setSession(session);
if (!session) {
throw new Error('Session cookie not found');
}
client.setSession(session);
// Return the services we want to use.
return {
@@ -57,15 +62,21 @@ export function createSessionClient(event) {
}
```
`APPWRITE_KEY`, `PUBLIC_APPWRITE_ENDPOINT` and `PUBLIC_APPWRITE_PROJECT_ID` are environment variables that are exported in your project's [.env file](https://kit.svelte.dev/docs/modules#$env-dynamic-public).
For example, your `.env` might look something similar to this.
You can get the values for these variables from the Appwrite console.
```text
APPWRITE_KEY=<YOUR_API_KEY>
PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
PUBLIC_APPWRITE_PROJECT=<YOUR_PROJECT_ID>
```
The `PUBLIC_APPWRITE_ENDPOINT` is the endpoint of your Appwrite project, and the `PUBLIC_APPWRITE_PROJECT` is the ID of the project you want to use.
You can get the values for these variables from the Appwrite console.
The `PUBLIC_APPWRITE_ENDPOINT` is the endpoint of your Appwrite project, and the `PUBLIC_APPWRITE_PROJECT` is the ID of the project you want to use.
You can get the values for these variables from the Appwrite console.
{% only_dark %}
![Create project screen](/images/docs/quick-starts/dark/create-project.png)
{% /only_dark %}
{% only_light %}
![Create project screen](/images/docs/quick-starts/create-project.png)
{% /only_light %}
@@ -74,21 +85,14 @@ The `APPWRITE_KEY` is an Appwrite API key with the necessary permissions to read
For this tutorial you'll need an API key with the following scopes:
| Category {% width=120 %} | Required scopes | Purpose |
|-----------|---------------------|---------|
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
| Category {% width=120 %} | Required scopes | Purpose |
| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ |
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
{% only_dark %}
![Server integrations](/images/docs/quick-starts/dark/integrate-server.png)
{% /only_dark %}
{% only_light %}
![Server integrations](/images/docs/quick-starts/integrate-server.png)
{% /only_light %}
For example, your `.env` might look something similar to this.
```text
APPWRITE_KEY=<YOUR_API_KEY>
PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
PUBLIC_APPWRITE_PROJECT=<YOUR_PROJECT_ID>
```

View File

@@ -13,12 +13,12 @@ Create a new file in the `src/hooks` directory called `server.js`:
import { createSessionClient } from '$lib/server/appwrite';
export async function handle({ event, resolve }) {
// Use our helper function to create the Appwrite client.
const { account } = createSessionClient(event);
// Let's store the current logged in user in locals,
// for easy access in our other routes.
try {
// Use our helper function to create the Appwrite client.
const { account } = createSessionClient(event);
// Store the current logged in user in locals,
// for easy access in our other routes.
event.locals.user = await account.get();
} catch {}
@@ -57,8 +57,8 @@ import { redirect } from '@sveltejs/kit';
export async function load({ locals }) {
// Access our user from locals.
if (!locals.user) {
// If no user is logged in, redirect to the sign in page.
throw redirect(301, '/signin');
// If no user is logged in, redirect to the sign up page.
throw redirect(301, '/signup');
}
// If the user is logged in, redirect to the account page.
@@ -66,4 +66,4 @@ export async function load({ locals }) {
}
```
When a user visits the home page, they will be redirected to the sign in page if they are not logged in, or to the account page if they are logged in.
When a user visits the home page, they will be redirected to the sign up page if they are not logged in, or to the account page if they are logged in.

View File

@@ -1,14 +1,14 @@
---
layout: tutorial
title: Create sign in page
title: Create sign up page
description: Add authentication to a SvelteKit project using Appwrite.
step: 5
---
We can now implement our sign in page. Create a `+page.svelte` file in the `src/routes/signin` directory:
We can now implement our sign up page. Create a `+page.svelte` file in the `src/routes/signup` directory:
```svelte
<!-- src/routes/signin/+page.svelte -->
<!-- src/routes/signup/+page.svelte -->
<form method="post">
<input id="email" placeholder="Email" type="email" />
<input id="password" placeholder="Password" type="password" />

View File

@@ -5,7 +5,7 @@ description: Add authentication to a SvelteKit project using Appwrite.
step: 6
---
Now the end-user is able to sign in, we can create the account page. This page will display basic information about the user, and allow the user to log out. Create a new file in the `src/routes/account` directory called `+page.server.js` and add the following code:
Now the end-user is able to sign up, we can create the account page. This page will display basic information about the user, and allow the user to log out. Create a new file in the `src/routes/account` directory called `+page.server.js` and add the following code:
```js
// src/routes/account/+page.server.js
@@ -14,7 +14,7 @@ import { redirect } from '@sveltejs/kit';
export async function load({ locals }) {
// Logged out users can't access this page.
if (!locals.user) throw redirect(301, '/signin');
if (!locals.user) throw redirect(301, '/signup');
// Pass the stored user local to the page.
return {
@@ -32,8 +32,8 @@ export const actions = {
await account.deleteSession('current');
event.cookies.delete(SESSION_COOKIE);
// Redirect to the sign in page.
throw redirect(301, '/signin');
// Redirect to the sign up page.
throw redirect(301, '/signup');
}
};
```

View File

@@ -1,18 +1,18 @@
---
layout: tutorial
title: OAuth2 authentication with SSR
title: OAuth authentication with SSR
description: Add authentication to a SvelteKit project using Appwrite.
step: 7
---
To support the OAuth2 flow, we first redirect the user to the OAuth2 provider, and then handle the callback from the OAuth2 provider.
To support the OAuth flow, we first redirect the user to the OAuth provider, and then handle the callback from the OAuth provider.
To redirect, add a button to our sign in page that redirects the user to the OAuth2 provider.
To redirect, add a button to our sign up page that redirects the user to the OAuth provider.
```svelte
<!-- src/routes/signin/+page.svelte -->
<!-- src/routes/signup/+page.svelte -->
<!-- ... existing sign in form -->
<!-- ... existing sign up form -->
<form action="/oauth2" method="post">
<button type="submit">Sign in with GitHub</button>
@@ -22,7 +22,7 @@ To redirect, add a button to our sign in page that redirects the user to the OAu
Add a new server route to handle the redirect.
```js
// src/routes/signin/+page.server.js
// src/routes/signup/+page.server.js
// ... existing imports
@@ -40,7 +40,7 @@ export const actions = {
const redirectURL = account.createOAuth2Token(
OAuthProvider.Github,
`${event.url.origin}/oauth2`,
`${event.url.origin}/signin`
`${event.url.origin}/signup`
);
throw redirect(url);
@@ -48,7 +48,7 @@ export const actions = {
};
```
The `createOAuth2Token` method redirects the user to the OAuth2 provider, and then the OAuth2 provider redirects the user back to the `/oauth2` route with the `userId` and `secret` URL query parameters.
The `createOAuth2Token` method redirects the user to the OAuth provider, and then the OAuth provider redirects the user back to the `/oauth2` route with the `userId` and `secret` URL query parameters.
Handle the callback and create a session for the user. Create a new server route at `src/routes/oauth2/+server.js`: