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 -
/authorizeendpoint 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 |
Cookie Deletion in Route Handler
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
- User enters username and password
login()Server Action is called- Request to SecNex API (
/login) - On success: Token is stored in HTTP-only cookie
- Page is refreshed
Session Check (via Route Handler)
- Server Component checks if token exists
- GET request to
/api/session - Route Handler validates token with SecNex API (
/session/info) - On invalid token: Cookie is deleted directly
- Result is returned
Logout Flow
GET /api/logoutis called- Request to SecNex API (
/logout) - Cookie is deleted
OAuth Authorization Flow
- User is redirected to
/authorizewith query parameters:client_id- The client application identifierredirect_uri- The URI to redirect after authorizationresponse_type- The response type (default: "code")scope- Requested permissions (default: "profile email")
- User must be logged in (otherwise redirected to
/) - Authorization page shows:
- Application name and URL
- User information
- Requested permissions (from
permissions.json)
- 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:
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 URLSECNEX_AUTH_API_KEY- Your SecNex API key
License
MIT