AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Auth Setup

skill-armaneker-claude-code-skills-auth-setup · by armaneker

>

No reviews yet
0 installs
43 views
0.0% view→install

Install

$ agentstack add skill-armaneker-claude-code-skills-auth-setup

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-armaneker-claude-code-skills-auth-setup)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Auth Setup? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Auth Setup

You are an expert in web authentication. Set up complete, production-safe auth with protected routes, sessions, and role-based access control.

Workflow

  1. Identify the framework: Next.js (default), Express, Fastify, other
  2. Choose the auth provider based on requirements:
  • NextAuth.js (Auth.js) — best for Next.js, supports many OAuth providers + credentials
  • Supabase Auth — best when already using Supabase DB; built-in email/OAuth/magic links
  • Clerk — best when you want a full UI + managed auth with minimal code
  1. Identify required auth methods: email+password, Google/GitHub OAuth, magic link, SSO

Option A: NextAuth.js (Auth.js v5)

Installation

npm install next-auth@beta
npx auth secret  # generates AUTH_SECRET

Configuration (auth.ts)

import NextAuth from 'next-auth';
import { PrismaAdapter } from '@auth/prisma-adapter';
import GitHub from 'next-auth/providers/github';
import Google from 'next-auth/providers/google';
import Credentials from 'next-auth/providers/credentials';
import { db } from '@/lib/db';
import bcrypt from 'bcryptjs';

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  session: { strategy: 'jwt' }, // use 'database' for server-side sessions
  providers: [
    GitHub({ clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! }),
    Google({ clientId: process.env.GOOGLE_ID!, clientSecret: process.env.GOOGLE_SECRET! }),
    Credentials({
      async authorize(credentials) {
        const { email, password } = credentials as { email: string; password: string };
        const user = await db.user.findUnique({ where: { email } });
        if (!user?.passwordHash) return null;
        const valid = await bcrypt.compare(password, user.passwordHash);
        return valid ? user : null;
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) { token.id = user.id; token.role = (user as any).role; }
      return token;
    },
    async session({ session, token }) {
      session.user.id = token.id as string;
      session.user.role = token.role as string;
      return session;
    },
  },
  pages: {
    signIn: '/login',
    error: '/login',
  },
});

Route Handler (app/api/auth/[...nextauth]/route.ts)

import { handlers } from '@/auth';
export const { GET, POST } = handlers;

Middleware — Protect Routes (middleware.ts)

import { auth } from '@/auth';
import { NextResponse } from 'next/server';

export default auth((req) => {
  const isLoggedIn = !!req.auth;
  const isProtected = req.nextUrl.pathname.startsWith('/dashboard') ||
                      req.nextUrl.pathname.startsWith('/settings');

  if (isProtected && !isLoggedIn) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
});

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

Server Component Auth Check

import { auth } from '@/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();
  if (!session) redirect('/login');

  return Welcome, {session.user.name};
}

Role-Based Access

// Type augmentation (types/next-auth.d.ts)
declare module 'next-auth' {
  interface User { role: string }
  interface Session { user: { id: string; role: string } & DefaultSession['user'] }
}

// In a server component or API route
const session = await auth();
if (session?.user.role !== 'admin') {
  redirect('/unauthorized');
}

Option B: Supabase Auth

Installation

npm install @supabase/supabase-js @supabase/ssr

Client Setup

// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export function createClient() {
  const cookieStore = cookies();
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return cookieStore.getAll(); },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options));
        },
      },
    }
  );
}

Sign Up / Sign In

// app/actions/auth.ts
'use server';
import { createClient } from '@/lib/supabase/server';
import { redirect } from 'next/navigation';

export async function signUp(email: string, password: string) {
  const supabase = createClient();
  const { error } = await supabase.auth.signUp({ email, password,
    options: { emailRedirectTo: `${process.env.APP_URL}/auth/callback` }
  });
  if (error) throw error;
  redirect('/check-email');
}

export async function signIn(email: string, password: string) {
  const supabase = createClient();
  const { error } = await supabase.auth.signInWithPassword({ email, password });
  if (error) throw error;
  redirect('/dashboard');
}

Middleware

// middleware.ts
import { createServerClient } from '@supabase/ssr';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export async function middleware(request: NextRequest) {
  let response = NextResponse.next({ request });
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    { cookies: { getAll: () => request.cookies.getAll(),
        setAll: (c) => { c.forEach(({ name, value, options }) => response.cookies.set(name, value, options)); } } }
  );

  const { data: { user } } = await supabase.auth.getUser();
  const isProtected = request.nextUrl.pathname.startsWith('/dashboard');

  if (isProtected && !user) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return response;
}

Option C: Clerk

Installation

npm install @clerk/nextjs

Provider (app/layout.tsx)

import { ClerkProvider } from '@clerk/nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    
      {children}
    
  );
}

Middleware

// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtected = createRouteMatcher(['/dashboard(.*)', '/settings(.*)']);

export default clerkMiddleware((auth, req) => {
  if (isProtected(req)) auth().protect();
});

export const config = { matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'] };

Access User in Server Components

import { currentUser } from '@clerk/nextjs/server';
import { redirect } from 'next/navigation';

export default async function Page() {
  const user = await currentUser();
  if (!user) redirect('/sign-in');
  return Hello {user.firstName};
}

Database Schema for Auth (NextAuth Prisma Adapter)

model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String? @db.Text
  access_token      String? @db.Text
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String? @db.Text
  session_state     String?
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  role          String    @default("user")
  passwordHash  String?
  accounts      Account[]
  sessions      Session[]
}

Common Pitfalls — Avoid These

  • Storing passwords in plain text — always bcrypt.hash(password, 12), never less than 10 rounds
  • Relying on client-side route guards only — always validate on the server (middleware or server component)
  • Not setting httpOnly: true on session cookies — prevents XSS token theft
  • Missing CSRF protection on credentials endpoints — NextAuth handles this; custom implementations must add it
  • Exposing JWT secret in client bundleAUTH_SECRET / NEXTAUTH_SECRET must only be in server env
  • Not invalidating sessions on password change — update session version or force re-login after password reset
  • Skipping email verification — at minimum, flag unverified accounts and limit their access

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.