smithery/xmark168

authentication

Implement authentication with NextAuth v5. Use when adding login/logout, checking sessions, protecting API routes, server actions, or pages.

Installation

$ npx skills add smithery/xmark168 --skill authentication

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/xmark168.

npx skills add smithery/xmark168

Browse all from smithery/xmark168

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,101 B
  • docs SUMMARY.md 162 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

This skill guides implementation of authentication using NextAuth v5, which is pre-configured in the boilerplate.

The user needs to protect routes, verify sessions, implement login/logout, or add role-based access control.

Before You Start

The authentication system is already configured:

  • Config file: src/auth.ts - Contains NextAuth configuration
  • Prisma adapter: User, Account, Session models in schema
  • Credentials provider: Username/password authentication ready

CRITICAL: Always check session before sensitive operations. Never trust client-side auth state for security decisions.

Server-Side Authentication

Use auth() from @/auth for all server-side auth checks:

import { auth } from '@/auth';
import { ApiErrors } from '@/lib/api-response';

// In API routes
const session = await auth();
if (!session) throw ApiErrors.unauthorized();
const userId = session.user.id;
// In Server Actions
'use server';
import { auth } from '@/auth';

const session = await auth();
if (!session) return { success: false, error: 'Unauthorized' };
// In Pages (Server Component)
import { auth } from '@/auth';
import { redirect } from 'next/navigation';

const session = await auth();
if (!session) redirect('/login');

Client-Side Authentication

Use useSession() from next-auth/react for client components:

'use client';
import { useSession, signIn, signOut } from 'next-auth/react';

export function AuthButton() {
  const { data: session, status } = useSession();
  
  if (status === 'loading') return <div>Loading...</div>;
  
  if (session) {
    return (
      <div>
        <span>{session.user.username}</span>
        <button onClick={() => signOut()}>Sign Out</button>
      </div>
    );
  }
  
  return <button onClick={() => signIn()}>Sign In</button>;
}

Login Form Implementation

'use client';
import { signIn } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';

export function LoginForm() {
  const router = useRouter();
  const [error, setError] = useState('');
  
  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    
    const result = await signIn('credentials', {
      username: formData.get('username'),
      password: formData.get('password'),
      redirect: false,
    });
    
    if (result?.error) {
      setError('Invalid credentials');
    } else {
      router.push('/dashboard');
    }
  }
  
  return (
    <form onSubmit={handleSubmit}>
      <input name="username" placeholder="Username" required />
      <input name="password" type="password" placeholder="Password" required />
      {error && <p className="text-destructive">{error}</p>}
      <button type="submit">Login</button>
    </form>
  );
}

Role-Based Access

Check user roles for authorization:

// In API Route
const session = await auth();
if (!session) throw ApiErrors.unauthorized();
if (session.user.role !== 'ADMIN') throw ApiErrors.forbidden();

// In Server Component
const session = await auth();
if (session?.user.role !== 'ADMIN') {
  return <div>Access denied</div>;
}
return <AdminPanel />;

Common Patterns

  • Get current user ID: session.user.id
  • Check if logged in: if (!session) throw ApiErrors.unauthorized()
  • Check role: session.user.role === 'ADMIN'
  • Redirect unauthenticated: if (!session) redirect('/login')
  • Client loading state: if (status === 'loading') return <Spinner />

NEVER:

  • Trust client-side session for security decisions
  • Store sensitive data in session
  • Skip auth checks in API routes that modify data
  • Use useSession in Server Components

IMPORTANT: The SessionProvider is already configured in the boilerplate layout. You don't need to add it again.