66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { cookies } from "next/headers";
|
|
import { SignJWT } from "jose";
|
|
|
|
// Secret key for JWT signing (in production, use environment variable)
|
|
const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET);
|
|
|
|
// Token expiration time (in seconds)
|
|
const TOKEN_EXPIRY = 60 * 60 * 12; // 12 hours (in seconds)
|
|
|
|
// This is your POST handler for the login endpoint
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const { email, password } = await request.json();
|
|
|
|
// --- Replace with your ACTUAL authentication logic ---
|
|
// In a real application, you would:
|
|
// 1. Query your database for the user by email.
|
|
// 2. Hash the provided password and compare it to the stored hashed password.
|
|
// 3. If credentials match, generate a secure JWT (JSON Web Token) or session ID.
|
|
// 4. Store the token/session ID securely (e.g., in a database or Redis).
|
|
|
|
// Mock authentication for demonstration purposes:
|
|
if (email === "admin@example.com" && password === "password123") {
|
|
// Create JWT token with expiration
|
|
const token = await new SignJWT({
|
|
email,
|
|
role: "admin",
|
|
iat: Math.floor(Date.now() / 1000), // issued at
|
|
})
|
|
.setProtectedHeader({ alg: "HS256" })
|
|
.setIssuedAt()
|
|
.setExpirationTime(Math.floor(Date.now() / 1000) + TOKEN_EXPIRY)
|
|
.sign(JWT_SECRET);
|
|
|
|
// Set the authentication token as an HTTP-only cookie
|
|
// HTTP-only cookies are crucial for security as they cannot be accessed by client-side JavaScript,
|
|
// which mitigates XSS attacks.
|
|
const cookieStore = await cookies();
|
|
cookieStore.set("auth_token", token, {
|
|
httpOnly: true, // IMPORTANT: Makes the cookie inaccessible to client-side scripts
|
|
secure: process.env.NODE_ENV === "production", // Use secure in production (HTTPS)
|
|
maxAge: TOKEN_EXPIRY, // 24 hours
|
|
path: "/", // Available across the entire site
|
|
sameSite: "lax", // Protects against CSRF
|
|
});
|
|
|
|
return NextResponse.json(
|
|
{ success: true, message: "Login successful" },
|
|
{ status: 200 }
|
|
);
|
|
} else {
|
|
return NextResponse.json(
|
|
{ success: false, message: "Invalid credentials" },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
} catch (error) {
|
|
console.error("Login API error:", error);
|
|
return NextResponse.json(
|
|
{ success: false, message: "Internal server error" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|