- JWT via jose (HS256, 7d expiry) - Login API: POST /api/auth/login → returns token - Verify API: GET /api/auth/me - Middleware checks Bearer header or cookie - Token stored in localStorage + cookie (for SSR) - Authentik button (disabled, placeholder) - Auth headers auto-added to API requests
28 lines
888 B
TypeScript
28 lines
888 B
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { verifyToken } from "@/lib/auth";
|
|
|
|
export async function middleware(req: NextRequest) {
|
|
// Check Authorization header (API calls)
|
|
const authHeader = req.headers.get("authorization");
|
|
if (authHeader) {
|
|
const token = authHeader.replace("Bearer ", "");
|
|
const payload = await verifyToken(token);
|
|
if (payload) return NextResponse.next();
|
|
return NextResponse.json({ error: "Invalid token" }, { status: 401 });
|
|
}
|
|
|
|
// Check cookie (browser navigation)
|
|
const token = req.cookies.get("tb_token")?.value;
|
|
if (token) {
|
|
const payload = await verifyToken(token);
|
|
if (payload) return NextResponse.next();
|
|
}
|
|
|
|
// Redirect to login
|
|
return NextResponse.redirect(new URL("/login", req.url));
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ["/((?!login|api/auth|_next/static|_next/image|favicon.ico).*)"],
|
|
};
|