mirror of
https://github.com/LukeHagar/website.git
synced 2025-12-10 21:07:46 +00:00
feat: update ssr dx nextjs
This commit is contained in:
@@ -23,21 +23,38 @@ Doing so could create security vulnerabilities.
|
|||||||
import { Client, Account } from "node-appwrite";
|
import { Client, Account } from "node-appwrite";
|
||||||
import { parseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
import { parseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
||||||
|
|
||||||
export const SESSION_COOKIE = "a_session";
|
// The name of your cookie that will store the session
|
||||||
|
export const SESSION_COOKIE = "my-custom-session";
|
||||||
|
|
||||||
export function createAppwriteClient(headers) {
|
// Admin client, used to create new accounts
|
||||||
|
export function createAdminClient() {
|
||||||
const client = new Client()
|
const client = new Client()
|
||||||
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
|
.setEndpoint(import.meta.env.PUBLIC_APPWRITE_ENDPOINT)
|
||||||
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!);
|
.setProject(import.meta.env.PUBLIC_APPWRITE_PROJECT_ID)
|
||||||
|
.setKey(import.meta.env.APPWRITE_KEY); // Set the API key here!
|
||||||
|
|
||||||
// Set the API key for the client, bypassing rate limiting and enabling
|
// Return the services you need
|
||||||
client.setKey(process.env.APPWRITE_KEY!);
|
return {
|
||||||
|
get account() {
|
||||||
|
return new Account(client);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the session from cookies and use it for the client
|
// Session client, used to make requests on behalf of the logged in user
|
||||||
const cookies = parseCookie(headers.get("cookie") ?? "");
|
export function createSessionClient(request) {
|
||||||
|
const client = new Client()
|
||||||
|
.setEndpoint(import.meta.env.PUBLIC_APPWRITE_ENDPOINT)
|
||||||
|
.setProject(import.meta.env.PUBLIC_APPWRITE_PROJECT_ID);
|
||||||
|
|
||||||
|
// Get the session cookie from the request and set the session
|
||||||
|
const cookies = parseCookies(request.headers.get("cookie") ?? "");
|
||||||
const session = cookies.get(SESSION_COOKIE);
|
const session = cookies.get(SESSION_COOKIE);
|
||||||
if (session) client.setSession(session);
|
if (session) {
|
||||||
|
client.setSession(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the services you need
|
||||||
return {
|
return {
|
||||||
get account() {
|
get account() {
|
||||||
return new Account(client);
|
return new Account(client);
|
||||||
@@ -64,8 +81,6 @@ For this tutorial you'll need an API key with the following scopes:
|
|||||||
|
|
||||||
| Category {% width=120 %} | Required scopes | Purpose |
|
| Category {% width=120 %} | Required scopes | Purpose |
|
||||||
|-----------|---------------------|---------|
|
|-----------|---------------------|---------|
|
||||||
| Accounts | `accounts.read` | Allows API key to read account information. |
|
|
||||||
| | `accounts.write` | Allows API key to create, update, and delete account information. |
|
|
||||||
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
|
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
|
||||||
|
|
||||||
{% only_dark %}
|
{% only_dark %}
|
||||||
|
|||||||
@@ -14,22 +14,19 @@ Edit the `src/server/appwrite.js` file to create a new function called `getLogge
|
|||||||
export async function getLoggedInUser(account) {
|
export async function getLoggedInUser(account) {
|
||||||
try {
|
try {
|
||||||
return await account.get();
|
return await account.get();
|
||||||
} catch {
|
} catch {}
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, use the `getLoggedInUser` function in the home page to redirect based on the user's login status. Create a new file in the `app` directory called `+page.jsx`.
|
Now, use the `getLoggedInUser` function in the home page to redirect based on the user's login status. Create a new file in the `app` directory called `+page.jsx`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createAppwriteClient, getLoggedInUser } from "@/lib/server/appwrite";
|
import { createSessionClient, getLoggedInUser } from "@/lib/server/appwrite";
|
||||||
|
|
||||||
import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
const { account } = createAppwriteClient(headers());
|
const { account } = createSessionClient(headers());
|
||||||
|
|
||||||
const user = await getLoggedInUser(account);
|
const user = await getLoggedInUser(account);
|
||||||
if (!user) redirect("/signin");
|
if (!user) redirect("/signin");
|
||||||
|
|||||||
@@ -11,13 +11,12 @@ We can now implement our sign in page. Create a `+page.jsx` file in the `src/app
|
|||||||
// src/app/sigin/+page.jsx
|
// src/app/sigin/+page.jsx
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createAppwriteClient,
|
createSessionClient,
|
||||||
getLoggedInUser,
|
getLoggedInUser,
|
||||||
} from "@/lib/server/appwrite";
|
} from "@/lib/server/appwrite";
|
||||||
|
|
||||||
|
|
||||||
export default async function SignInPage() {
|
export default async function SignInPage() {
|
||||||
const { account } = createAppwriteClient(headers());
|
const { account } = createSessionClient(headers());
|
||||||
|
|
||||||
const user = await getLoggedInUser(account);
|
const user = await getLoggedInUser(account);
|
||||||
if (user) redirect("/account");
|
if (user) redirect("/account");
|
||||||
@@ -53,7 +52,7 @@ This is an HTML form with an email and password input. When the form is submitte
|
|||||||
|
|
||||||
// previous imports ...
|
// previous imports ...
|
||||||
|
|
||||||
import { SESSION_COOKIE } from "@/lib/server/appwrite";
|
import { SESSION_COOKIE, createAdminClient } from "@/lib/server/appwrite";
|
||||||
import { cookies, headers } from "next/headers";
|
import { cookies, headers } from "next/headers";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ async function signInWithEmail(formData) {
|
|||||||
const email = formData.get("email");
|
const email = formData.get("email");
|
||||||
const password = formData.get("password");
|
const password = formData.get("password");
|
||||||
|
|
||||||
const { account } = createAppwriteClient(headers());
|
const { account } = createAdminClient();
|
||||||
|
|
||||||
const session = await account.createEmailPasswordSession(email, password);
|
const session = await account.createEmailPasswordSession(email, password);
|
||||||
|
|
||||||
@@ -80,4 +79,4 @@ async function signInWithEmail(formData) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `signInWithEmail` function is an async function that takes the form data as an argument. It uses the `createAppwriteClient` function to create an Appwrite client and then calls the `createEmailPasswordSession` method on the `account` object. This method takes the email and password as arguments and returns a session object. We then set the session secret in a cookie and redirect the user to the account page.
|
The `signInWithEmail` function is an async function that takes the form data as an argument. It uses the `createAdminClient` function to create an admin Appwrite client and then calls the `createEmailPasswordSession` method on the `account` object. This method takes the email and password as arguments and returns a session object. We then set the session secret in a cookie and redirect the user to the account page.
|
||||||
@@ -11,7 +11,7 @@ Now the end-user is able to sign in, we can create the account page. This page w
|
|||||||
// src/app/account/page.jsx
|
// src/app/account/page.jsx
|
||||||
import {
|
import {
|
||||||
SESSION_COOKIE,
|
SESSION_COOKIE,
|
||||||
createAppwriteClient,
|
createSessionClient,
|
||||||
getLoggedInUser,
|
getLoggedInUser,
|
||||||
} from "@/lib/server/appwrite";
|
} from "@/lib/server/appwrite";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
@@ -20,7 +20,7 @@ import { cookies, headers } from "next/headers";
|
|||||||
async function signOut() {
|
async function signOut() {
|
||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
const { account } = createAppwriteClient(headers());
|
const { account } = createSessionClient(headers());
|
||||||
|
|
||||||
cookies().delete(SESSION_COOKIE);
|
cookies().delete(SESSION_COOKIE);
|
||||||
await account.deleteSession("current");
|
await account.deleteSession("current");
|
||||||
@@ -29,7 +29,7 @@ async function signOut() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function HomePage() {
|
export default async function HomePage() {
|
||||||
const { account } = createAppwriteClient(headers());
|
const { account } = createSessionClient(headers());
|
||||||
|
|
||||||
const user = await getLoggedInUser(account);
|
const user = await getLoggedInUser(account);
|
||||||
if (!user) redirect("/signin");
|
if (!user) redirect("/signin");
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Add a new server action. Navigate to `src/lib/server` and create a new file `oau
|
|||||||
```js
|
```js
|
||||||
// src/lib/server/oauth2.js
|
// src/lib/server/oauth2.js
|
||||||
|
|
||||||
import { SESSION_COOKIE, createAppwriteClient } from "@/lib/server/appwrite";
|
import { SESSION_COOKIE, createAdminClient } from "@/lib/server/appwrite";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
async function signInWithGithub(formData) {
|
async function signInWithGithub(formData) {
|
||||||
@@ -20,7 +20,7 @@ async function signInWithGithub(formData) {
|
|||||||
|
|
||||||
const provider = formData.get('provider') ?? 'github';
|
const provider = formData.get('provider') ?? 'github';
|
||||||
|
|
||||||
const { account } = createAppwriteClient();
|
const { account } = createAdminClient();
|
||||||
const redirectURL = await account.createOAuth2Token(
|
const redirectURL = await account.createOAuth2Token(
|
||||||
provider,
|
provider,
|
||||||
'<YOUR_WEBSITE_DOMAIN>/oauth2',
|
'<YOUR_WEBSITE_DOMAIN>/oauth2',
|
||||||
@@ -53,7 +53,7 @@ Handle the callback and create a session for the user. Create a new Next.js serv
|
|||||||
```js
|
```js
|
||||||
// src/app/oauth2/route.js
|
// src/app/oauth2/route.js
|
||||||
|
|
||||||
import { SESSION_COOKIE, createAppwriteClient } from "@/lib/server/appwrite";
|
import { SESSION_COOKIE, createAdminClient } from "@/lib/server/appwrite";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ export async function GET(request) {
|
|||||||
const userId = request.nextUrl.searchParams.get("userId");
|
const userId = request.nextUrl.searchParams.get("userId");
|
||||||
const secret = request.nextUrl.searchParams.get("secret");
|
const secret = request.nextUrl.searchParams.get("secret");
|
||||||
|
|
||||||
const { account } = createAppwriteClient(request.headers);
|
const { account } = createAdminClient();
|
||||||
const session = await account.createSession(userId, secret);
|
const session = await account.createSession(userId, secret);
|
||||||
|
|
||||||
cookies().set(SESSION_COOKIE, session.secret, {
|
cookies().set(SESSION_COOKIE, session.secret, {
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ For this tutorial you'll need an API key with the following scopes:
|
|||||||
|
|
||||||
| Category {% width=120 %} | Required scopes | Purpose |
|
| Category {% width=120 %} | Required scopes | Purpose |
|
||||||
|-----------|---------------------|---------|
|
|-----------|---------------------|---------|
|
||||||
| Accounts | `accounts.read` | Allows API key to read account information. |
|
|
||||||
| | `accounts.write` | Allows API key to create, update, and delete account information. |
|
|
||||||
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
|
| Sessions | `sessions.write` | Allows API key to create, update, and delete sessions. |
|
||||||
|
|
||||||
{% only_dark %}
|
{% only_dark %}
|
||||||
|
|||||||
Reference in New Issue
Block a user