@authaction/server-sdk
v0.1.0
Published
AuthAction server-side SDK — session-based auth for Next.js, Nuxt, Remix, and SvelteKit
Maintainers
Readme
@authaction/server-sdk
Server-side session auth for Next.js, Nuxt, Remix, and SvelteKit. Handles the full OAuth2 PKCE flow server-side — exchanges the authorization code, encrypts tokens in an HTTP-only cookie session, and provides helpers for reading the session in server components and route handlers.
For browser-side (SPA) auth use
@authaction/web-sdk.
For API JWT verification use@authaction/node-sdk.
Installation
npm install @authaction/server-sdkHow it works
GET /auth/login → generate PKCE → store state + verifier in cookie → redirect to AuthAction
GET /auth/callback → validate state → exchange code for tokens → set encrypted session cookie
GET /auth/logout → clear session cookie → redirect to AuthAction /oidc/logoutSessions are stored as JWE-encrypted HTTP-only cookies (AES-256-GCM, key derived from sessionSecret).
Next.js
1. Create the catch-all route handler
// app/api/auth/[...authaction]/route.ts
import { createNextHandlers } from '@authaction/server-sdk/nextjs';
export const { GET } = createNextHandlers({
domain: process.env.AUTHACTION_DOMAIN!,
clientId: process.env.AUTHACTION_CLIENT_ID!,
clientSecret: process.env.AUTHACTION_CLIENT_SECRET,
redirectUri: process.env.AUTHACTION_REDIRECT_URI!,
postLogoutRedirectUri: process.env.AUTHACTION_LOGOUT_REDIRECT_URI,
sessionSecret: process.env.SESSION_SECRET!,
});Handles automatically:
GET /api/auth/login→ redirect to AuthActionGET /api/auth/callback→ exchange code, set sessionGET /api/auth/logout→ clear session, redirect to AuthAction
2. Protect routes with middleware
// middleware.ts
import { createAuthMiddleware } from '@authaction/server-sdk/nextjs';
export default createAuthMiddleware({
sessionSecret: process.env.SESSION_SECRET!,
protectedPaths: ['/dashboard', '/profile'],
loginPath: '/api/auth/login',
});
export const config = { matcher: ['/dashboard/:path*', '/profile/:path*'] };3. Read the session in Server Components
// app/dashboard/page.tsx
import { getSessionFromRequest } from '@authaction/server-sdk/nextjs';
import { cookies } from 'next/headers';
export default async function DashboardPage() {
// Option A — via route handler request object
// Option B — build a request from cookies for server components
const session = ...; // use getSessionFromRequest(req, config)
if (!session) redirect('/api/auth/login');
return <div>Hello {session.user.name}</div>;
}Remix
// app/auth.server.ts
import { createRemixAuth } from '@authaction/server-sdk/remix';
export const auth = createRemixAuth({
domain: process.env.AUTHACTION_DOMAIN!,
clientId: process.env.AUTHACTION_CLIENT_ID!,
redirectUri: process.env.AUTHACTION_REDIRECT_URI!,
sessionSecret: process.env.SESSION_SECRET!,
});// app/routes/auth.login.tsx
export const loader = ({ request }: LoaderFunctionArgs) => auth.handleLogin(request);
// app/routes/auth.callback.tsx
export const loader = ({ request }: LoaderFunctionArgs) => auth.handleCallback(request);
// app/routes/auth.logout.tsx
export const action = ({ request }: ActionFunctionArgs) => auth.handleLogout(request);
// app/routes/dashboard.tsx
export async function loader({ request }: LoaderFunctionArgs) {
const session = await auth.requireSession(request); // redirects to /auth/login if missing
return { user: session.user };
}Nuxt
// server/api/auth/[...].ts
import { createNuxtHandlers } from '@authaction/server-sdk/nuxt';
import { defineEventHandler, getCookie, setCookie, deleteCookie, getQuery, sendRedirect, createError } from 'h3';
const { handler } = createNuxtHandlers(
{
domain: process.env.AUTHACTION_DOMAIN!,
clientId: process.env.AUTHACTION_CLIENT_ID!,
redirectUri: process.env.AUTHACTION_REDIRECT_URI!,
sessionSecret: process.env.SESSION_SECRET!,
},
{ defineEventHandler, getCookie, setCookie, deleteCookie, getQuery, sendRedirect, createError },
);
export default handler;Handles: /api/auth/login, /api/auth/callback, /api/auth/logout, /api/auth/session
SvelteKit
// src/lib/auth.server.ts
import { createSvelteAuth } from '@authaction/server-sdk/svelte';
import { env } from '$env/dynamic/private';
export const auth = createSvelteAuth({
domain: env.AUTHACTION_DOMAIN,
clientId: env.AUTHACTION_CLIENT_ID,
redirectUri: env.AUTHACTION_REDIRECT_URI,
sessionSecret: env.SESSION_SECRET,
});// src/routes/auth/login/+server.ts
import { auth } from '$lib/auth.server';
export const GET = (event) => auth.handleLogin(event);
// src/routes/auth/callback/+server.ts
export const GET = (event) => auth.handleCallback(event);
// src/routes/auth/logout/+server.ts
export const GET = (event) => auth.handleLogout(event);
// src/hooks.server.ts — populates event.locals.session on every request
import { auth } from '$lib/auth.server';
export const handle = auth.handle;
// src/routes/dashboard/+page.server.ts
export async function load({ locals }) {
if (!locals.session) throw redirect(302, '/auth/login');
return { user: locals.session.user };
}Configuration
| Option | Required | Description |
|---|---|---|
| domain | ✓ | AuthAction tenant domain |
| clientId | ✓ | OAuth2 client ID |
| clientSecret | | Client secret (recommended for server apps) |
| redirectUri | ✓ | Callback URL after login |
| postLogoutRedirectUri | | Redirect URL after logout |
| sessionSecret | ✓ | Secret for session cookie encryption (32+ chars) |
| sessionCookieName | | Cookie name (default: __aa_session) |
| cookieMaxAge | | Session TTL in seconds (default: 7 days) |
| loginRedirect | | Post-login redirect (default: /) |
Session data
interface SessionData {
user: {
sub: string;
name?: string;
email?: string;
[key: string]: unknown;
};
accessToken: string;
refreshToken?: string;
expiresAt: number; // Unix timestamp (ms)
}Environment variables
AUTHACTION_DOMAIN=your-tenant.eu.authaction.com
AUTHACTION_CLIENT_ID=your-client-id
AUTHACTION_CLIENT_SECRET=your-client-secret # optional
AUTHACTION_REDIRECT_URI=http://localhost:3000/auth/callback
AUTHACTION_LOGOUT_REDIRECT_URI=http://localhost:3000
SESSION_SECRET=a-random-string-at-least-32-characters-longLicense
MIT
