Salta ai contenuti

Scalekit & Astro

Questi contenuti non sono ancora disponibili nella tua lingua.

Scalekit is an authentication platform built for B2B and AI applications. It provides social login, enterprise SSO, magic links, and more — managing the full OAuth 2.0 / OIDC flow so you get back tokens and a user profile without building any login UI. A single Scalekit environment supports multiple applications (for example, app.yourcompany.com and docs.yourcompany.com), so your users authenticate once and share the same session across all your properties.

  • A Scalekit account and environment. If you don’t have one, you can sign up for free at scalekit.com and create a new environment.
  • An Astro project with output: 'server' for on-demand rendering enabled.
  • Scalekit credentials for your environment. You can find these in the Settings > API Credentials section of your Scalekit dashboard.
    • SCALEKIT_ENVIRONMENT_URL: The URL of your Scalekit environment.
    • SCALEKIT_CLIENT_ID: Your Scalekit client ID.
    • SCALEKIT_CLIENT_SECRET: Your Scalekit client secret.
    • SCALEKIT_REDIRECT_URI: The callback URL Scalekit will redirect to after login (e.g. http://localhost:4321/api/auth/callback). Register this in your Scalekit dashboard under Settings > Redirects.

To add your Scalekit credentials to your Astro project, add the following to your .env file:

.env
SCALEKIT_ENVIRONMENT_URL=YOUR_SCALEKIT_ENVIRONMENT_URL
SCALEKIT_CLIENT_ID=YOUR_SCALEKIT_CLIENT_ID
SCALEKIT_CLIENT_SECRET=YOUR_SCALEKIT_CLIENT_SECRET
SCALEKIT_REDIRECT_URI=http://localhost:4321/api/auth/callback

Now, these environment variables are available in your project.

If you would like to have IntelliSense for your environment variables, edit or create the env.d.ts in your src/ directory and add the following:

src/env.d.ts
/// <reference types="astro/client" />
interface ImportMetaEnv {
readonly SCALEKIT_ENVIRONMENT_URL: string;
readonly SCALEKIT_CLIENT_ID: string;
readonly SCALEKIT_CLIENT_SECRET: string;
readonly SCALEKIT_REDIRECT_URI: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
declare namespace App {
interface Locals {
user?: {
sub: string;
email?: string;
name?: string;
};
}
}
Read more about environment variables and .env files in Astro.

Your project should now include these files:

  • Directorysrc/
    • env.d.ts
  • .env
  • astro.config.mjs
  • package.json

To connect to Scalekit, install @scalekit-sdk/node in your project.

Terminal window
npm install @scalekit-sdk/node

Next, create a folder named lib in your src/ directory and add a Scalekit client file:

src/lib/scalekit.ts
import { ScalekitClient } from "@scalekit-sdk/node";
export const scalekit = new ScalekitClient(
import.meta.env.SCALEKIT_ENVIRONMENT_URL,
import.meta.env.SCALEKIT_CLIENT_ID,
import.meta.env.SCALEKIT_CLIENT_SECRET,
);
export const REDIRECT_URI =
import.meta.env.SCALEKIT_REDIRECT_URI ?? "http://localhost:4321/api/auth/callback";

Now, your project should include these files:

  • Directorysrc/
    • Directorylib/
      • scalekit.ts
    • env.d.ts
  • .env
  • package.json

Scalekit handles authentication through a standard OAuth 2.0 / OIDC redirect flow. Your app sends users to Scalekit, they sign in, and Scalekit redirects them back to your callback URL with an authorization code you exchange for tokens. This guide uses the Authorization Code flow with a client secret, which is appropriate for server-side rendered applications.

To add authentication to your project, you will need to create three server endpoints:

  • GET /api/auth/login: redirects users to Scalekit to sign in.
  • GET /api/auth/callback: exchanges the authorization code for tokens and sets session cookies.
  • GET /api/auth/logout: clears session cookies and ends the Scalekit session.

Create these endpoints in the src/pages/api/auth/ directory of your project. Your project should now include these new files:

  • Directorysrc/
    • Directorylib/
      • scalekit.ts
    • Directorypages/
      • Directoryapi/
        • Directoryauth/
          • login.ts
          • callback.ts
          • logout.ts
    • env.d.ts
  • .env
  • astro.config.mjs
  • package.json

login.ts generates an authorization URL and redirects the user to Scalekit to sign in.

src/pages/api/auth/login.ts
import type { APIRoute } from "astro";
import { scalekit, REDIRECT_URI } from "../../../lib/scalekit";
export const GET: APIRoute = async () => {
const url = scalekit.getAuthorizationUrl(REDIRECT_URI, {
scopes: ["openid", "profile", "email", "offline_access"],
});
return Response.redirect(url);
};

callback.ts receives the authorization code from Scalekit, exchanges it for tokens, and stores them in HttpOnly cookies.

src/pages/api/auth/callback.ts
import type { APIRoute } from "astro";
import { scalekit, REDIRECT_URI } from "../../../lib/scalekit";
export const GET: APIRoute = async ({ request, cookies }) => {
const url = new URL(request.url);
const code = url.searchParams.get("code");
if (!code) {
return Response.redirect(new URL("/", request.url).origin);
}
const { user, idToken, accessToken, refreshToken } =
await scalekit.authenticateWithCode(code, REDIRECT_URI);
const secure = url.protocol === "https:";
const cookieOptions = { httpOnly: true, path: "/", sameSite: "lax" as const, secure };
cookies.set("sk-id-token", idToken, cookieOptions);
cookies.set("sk-access-token", accessToken, cookieOptions);
cookies.set("sk-refresh-token", refreshToken, cookieOptions);
return Response.redirect(new URL("/", request.url).origin);
};

logout.ts clears the session cookies and redirects to Scalekit’s logout endpoint to end the Scalekit session.

src/pages/api/auth/logout.ts
import type { APIRoute } from "astro";
import { scalekit } from "../../../lib/scalekit";
export const GET: APIRoute = async ({ request, cookies }) => {
const idToken = cookies.get("sk-id-token")?.value;
cookies.delete("sk-id-token", { path: "/" });
cookies.delete("sk-access-token", { path: "/" });
cookies.delete("sk-refresh-token", { path: "/" });
const logoutUrl = scalekit.getLogoutUrl({
idTokenHint: idToken,
postLogoutRedirectUri: new URL("/", request.url).origin,
});
return Response.redirect(logoutUrl);
};

Create a src/middleware.ts file to validate the access token on every request and populate Astro.locals.user with the authenticated user’s profile. When the access token has expired, the middleware automatically refreshes it using the refresh token.

src/middleware.ts
import { defineMiddleware } from "astro:middleware";
import type { IdTokenClaim } from "@scalekit-sdk/node";
import { scalekit } from "./lib/scalekit";
export const onRequest = defineMiddleware(async (context, next) => {
const accessToken = context.cookies.get("sk-access-token")?.value;
if (accessToken) {
try {
const claims = await scalekit.validateToken<IdTokenClaim>(accessToken);
context.locals.user = {
sub: claims.sub,
email: claims.email,
name: claims.name,
};
} catch {
// Access token invalid or expired — try to refresh
const refreshToken = context.cookies.get("sk-refresh-token")?.value;
if (refreshToken) {
try {
const { accessToken: newToken } =
await scalekit.refreshAccessToken(refreshToken);
const secure = new URL(context.request.url).protocol === "https:";
context.cookies.set("sk-access-token", newToken, {
httpOnly: true,
path: "/",
sameSite: "lax",
secure,
});
const claims = await scalekit.validateToken<IdTokenClaim>(newToken);
context.locals.user = {
sub: claims.sub,
email: claims.email,
name: claims.name,
};
} catch {
// Refresh failed — clear session cookies
context.cookies.delete("sk-id-token", { path: "/" });
context.cookies.delete("sk-access-token", { path: "/" });
context.cookies.delete("sk-refresh-token", { path: "/" });
}
}
}
}
return next();
});

Now that your middleware populates Astro.locals.user, you can create pages that show different content based on authentication state.

dashboard.astro is a page that is only accessible to authenticated users. It reads the user from Astro.locals, set by the middleware, and redirects to the home page if the user is not signed in.

src/pages/dashboard.astro
---
import Layout from "../layouts/Layout.astro";
const user = Astro.locals.user;
if (!user) {
return Astro.redirect("/");
}
---
<Layout title="Dashboard">
<h1>Welcome, {user.name ?? user.email}</h1>
<p>You are signed in.</p>
<a href="/api/auth/logout">Sign out</a>
</Layout>

Altre guide per servizi backend

Contribuisci Comunità Sponsor