Skip to content

Astro SSR

OAuth authentication with SSR_

Add authentication to a Astro project using Appwrite.

1 min read

Raw

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 up page that redirects the user to the OAuth provider.

JavaScript
<!-- src/pages/signup.astro -->
<!-- ... existing sign up form -->
<form action="/oauth" method="post">
<button type="submit">Sign up with GitHub</button>
</form>

Add a new POST route to handle the redirect.

JavaScript
// src/pages/oauth.js
import crypto from "node:crypto";
import { createAdminClient } from "../server/appwrite";
import { OAuthProvider } from "node-appwrite";
export const POST = async ({ redirect, url, cookies }) => {
// Create the Appwrite client
const { account } = createAdminClient();
// A random value only this browser will hold, checked in the callback
const state = crypto.randomBytes(32).toString("hex");
cookies.set("oauth-state", state, {
path: "/",
httpOnly: true,
sameSite: "lax",
secure: true,
maxAge: 600,
});
// Create an OAuth token
const redirectUrl = await account.createOAuth2Token({
provider: OAuthProvider.Github,
success: `${url.origin}/oauth`,
failure: `${url.origin}/signup`,
state: state,
});
// Redirect the end-user to the OAuth2 provider authentication
return redirect(redirectUrl);
};

The createOAuth2Token method returns a URL to the OAuth provider. After authentication the OAuth provider redirects the user back to the /oauth route with the userId, secret and state URL query parameters. The state is the value stored in the oauth-state cookie, which lets the callback check that this browser started the sign-in.

Create a new GET route to handle the callback and create a session for the user.

JavaScript
// src/pages/oauth.js
import { createAdminClient, SESSION_COOKIE } from "../server/appwrite";
import { OAuthProvider } from "node-appwrite";
// ... existing POST handler
export const GET = async ({ redirect, cookies, url }) => {
// Get the user ID and secret from the URL
const userId = url.searchParams.get("userId");
const secret = url.searchParams.get("secret");
const state = url.searchParams.get("state");
// Only accept a sign-in this browser started
const expected = cookies.get("oauth-state")?.value;
cookies.delete("oauth-state", { path: "/" });
if (!expected || state !== expected) {
return redirect("/signup");
}
// Create the Appwrite client
const { account } = createAdminClient();
// Exchange the token for a session
const session = await account.createSession({
userId,
secret
});
// Set the session cookie
cookies.set(SESSION_COOKIE, session.secret, {
sameSite: "lax",
expires: new Date(session.expire),
secure: true,
httpOnly: true,
path: "/",
});
// Redirect the logged in user to the account page
return redirect("/account");
};

Was this page helpful?

Share what worked or what we should fix. Once approved, our agents automatically apply suggested updates to the docs.