2026-01-21 06:40:53 +01:00
2026-01-21 06:40:53 +01:00
2026-01-21 06:40:53 +01:00
2026-01-19 08:42:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-15 20:08:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-19 08:42:07 +01:00
2026-01-21 06:40:53 +01:00

SecNex Auth Login

A Next.js 15 application for authentication with SecNex. The application uses Server Actions for login/logout and Route Handlers for session checks. Authentication tokens are managed via HTTP-only cookies.

Features

  • Login Form - Username/password authentication with form validation
  • OAuth Authorization Flow - /authorize endpoint for third-party app authorization
  • Session Management - Token validation and automatic cleanup
  • Social Login Buttons - GitHub and Google OAuth buttons (UI only)
  • Responsive UI - Built with shadcn/ui components
  • Toast Notifications - User feedback using Sonner

Project Structure

auth-login/
├── app/
│   ├── api/
│   │   ├── logout/
│   │   │   └── route.tsx         # Route Handler for logout
│   │   └── session/
│   │       └── route.ts          # Route Handler for session check
│   ├── authorize/
│   │   └── page.tsx              # OAuth authorization page
│   ├── layout.tsx                # Root layout with fonts
│   └── page.tsx                  # Home page (Login / Success)
├── components/
│   ├── core/
│   │   ├── login-form.tsx        # Login form components (Client Components)
│   │   ├── authorize.tsx         # OAuth authorization component
│   │   ├── social-login-button.tsx
│   │   └── loading.tsx           # Loading spinner component
│   ├── server/
│   │   └── login.tsx             # Server Actions for login
│   └── ui/                       # UI components (shadcn/ui)
├── lib/
│   └── utils.ts                  # Utility functions
└── permissions.json              # OAuth scope permissions

Technical Details

Route Handlers vs Server Actions

In Next.js 15, cookies can only be modified in the following contexts:

  • Route Handlers (API routes under app/api/)
  • Server Actions with "use server" directive

Key Difference:

  • Route Handlers can ALWAYS modify cookies
  • Server Actions CANNOT modify cookies when called from a Server Component

Architecture Decisions

Operation Type Reason
Login Server Action Called from Client Components
Session Check Route Handler Called from Server Component, needs cookie deletion ability
Logout Route Handler Called from Client Component via fetch

Problem: The original code attempted to delete cookies in a Server Action called from a Server Component, resulting in:

Error: Cookies can only be modified in a Server Action or Route Handler.

Solution: The session check was moved to a Route Handler (app/api/session/route.ts). Route Handlers always have access to cookie modification, regardless of the caller.

Getting Started

Prerequisites

  • Node.js 18+
  • pnpm

Environment Variables

Create a .env.local file in the root directory:

SECNEX_AUTH_API_HOST=http://localhost:3001
SECNEX_AUTH_API_KEY=your_api_key_here

Installation

pnpm install

Development Server

pnpm dev

The application will be available at http://localhost:3000.

Build

pnpm build

Production

pnpm start

How It Works

Login Flow

  1. User enters username and password
  2. login() Server Action is called
  3. Request to SecNex API (/login)
  4. On success: Token is stored in HTTP-only cookie
  5. Page is refreshed

Session Check (via Route Handler)

  1. Server Component checks if token exists
  2. GET request to /api/session
  3. Route Handler validates token with SecNex API (/session/info)
  4. On invalid token: Cookie is deleted directly
  5. Result is returned

Logout Flow

  1. GET /api/logout is called
  2. Request to SecNex API (/logout)
  3. Cookie is deleted

OAuth Authorization Flow

  1. User is redirected to /authorize with query parameters:
    • client_id - The client application identifier
    • redirect_uri - The URI to redirect after authorization
    • response_type - The response type (default: "code")
    • scope - Requested permissions (default: "profile email")
  2. User must be logged in (otherwise redirected to /)
  3. Authorization page shows:
    • Application name and URL
    • User information
    • Requested permissions (from permissions.json)
  4. User can authorize or deny the request

API Endpoints

Server Actions

login(username, password)

Performs login and stores the token in a cookie.

const response = await login("user", "password");
// { success: boolean, message: string, token?: string }

Route Handlers

GET /api/session

Validates the token and returns session information. Automatically deletes the cookie on invalid token.

const response = await fetch("/api/session");
const data = await response.json();
// { success: boolean, message: string, sessionInfo?: { username, email, role } }

GET /api/logout

Logs out the user and deletes the token.

const response = await fetch("/api/logout");
const data = await response.json();
// { success: boolean, message: string }

Components

LoginContainer

Displays the login form.

<LoginContainer applicationName="SecNex" applicationLogo="/logo.png" />

LoginSuccessContainer

Displays the success page after login.

<LoginSuccessContainer
  applicationName="SecNex"
  applicationLogo="/logo.png"
/>

AuthorizeContainer

Displays the OAuth authorization page.

<AuthorizeContainer
  applicationName="My App"
  applicationUrl="https://example.com"
  applicationLogo="/app-logo.png"
  client_id="abc123"
  redirect_uri="https://example.com/callback"
  response_type="code"
  scope="profile email"
/>

Permissions

The permissions.json file defines OAuth scope permissions:

{
  "profile": {
    "name": "Profile Information",
    "description": "View your name and profile picture"
  },
  "email": {
    "name": "Email Address",
    "description": "View your email address"
  }
}

Important Notes

  • Server Actions use "use server" directive
  • Route Handlers allow cookie modification from Server Components
  • Cookies are HTTP-only for additional security
  • The SecNex API must be running at the configured SECNEX_AUTH_API_HOST
  • API credentials should be stored in environment variables (not hardcoded)

Tech Stack

  • Next.js 15 - React framework
  • React 19 - UI library
  • TypeScript - Type safety
  • Tailwind CSS - Styling
  • shadcn/ui - UI components
  • Radix UI - Headless UI primitives
  • React Hook Form - Form management
  • Zod - Schema validation
  • Sonner - Toast notifications
  • Tabler Icons - Icon library

Deployment

Vercel

The easiest way to deploy is using the Vercel platform:

https://vercel.com/new

For more information, see the Next.js Deployment Documentation.

Environment Variables

Make sure to set the following environment variables in your deployment:

  • SECNEX_AUTH_API_HOST - Your SecNex API host URL
  • SECNEX_AUTH_API_KEY - Your SecNex API key

License

MIT

Description
No description provided
Readme 175 KiB
Languages
TypeScript 94.3%
CSS 5.5%
JavaScript 0.2%