init: Initial commit
This commit is contained in:
285
README.md
285
README.md
@@ -1,36 +1,281 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
# 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 |
|
||||
|
||||
### 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
|
||||
|
||||
First, run the development server:
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 18+
|
||||
- pnpm
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Create a `.env.local` file in the root directory:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
SECNEX_API_HOST=http://localhost:3001
|
||||
SECNEX_API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
### Installation
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
### Development Server
|
||||
|
||||
## Learn More
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
The application will be available at [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
### Build
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
```bash
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## Deploy on Vercel
|
||||
### Production
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
```bash
|
||||
pnpm start
|
||||
```
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
## 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.
|
||||
|
||||
```typescript
|
||||
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.
|
||||
|
||||
```typescript
|
||||
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.
|
||||
|
||||
```typescript
|
||||
const response = await fetch("/api/logout");
|
||||
const data = await response.json();
|
||||
// { success: boolean, message: string }
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### `LoginContainer`
|
||||
|
||||
Displays the login form.
|
||||
|
||||
```tsx
|
||||
<LoginContainer applicationName="SecNex" applicationLogo="/logo.png" />
|
||||
```
|
||||
|
||||
### `LoginSuccessContainer`
|
||||
|
||||
Displays the success page after login.
|
||||
|
||||
```tsx
|
||||
<LoginSuccessContainer
|
||||
applicationName="SecNex"
|
||||
applicationLogo="/logo.png"
|
||||
/>
|
||||
```
|
||||
|
||||
### `AuthorizeContainer`
|
||||
|
||||
Displays the OAuth authorization page.
|
||||
|
||||
```tsx
|
||||
<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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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_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](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme)
|
||||
|
||||
For more information, see the [Next.js Deployment Documentation](https://nextjs.org/docs/app/building-your-application/deploying).
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Make sure to set the following environment variables in your deployment:
|
||||
|
||||
- `SECNEX_API_HOST` - Your SecNex API host URL
|
||||
- `SECNEX_API_KEY` - Your SecNex API key
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user