역할: 사용자의 이메일/비밀번호를 받아 JWT 토큰 발급
위치: pages/api/auth/login.ts
동작:
localStorage
에 저장HttpOnly Cookie
로 저장예시 코드:
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
credentials: "include",
});
구분 | 저장 위치 | 유효기간 | 설명 |
---|---|---|---|
Access Token | localStorage | 15분 | 클라이언트에서 API 요청 시 Authorization 헤더에 사용 |
Refresh Token | HttpOnly 쿠키 | 7일 | 만료된 Access Token 재발급에 사용 |
JWT 발급 유틸 (lib/auth.ts):
export async function generateAccessToken(payload: JWTPayload) {
return await new SignJWT(payload)
.setProtectedHeader({ alg: "HS256" })
.setExpirationTime("15m")
.sign(secret);
}
JWT 검증:
export async function verifyToken(token: string) {
try {
return await jwtVerify(token, secret);
} catch (e) {
return null;
}
}
역할: 페이지 접근 전 쿠키에 있는 refreshToken
검사
위치: middleware.ts
(루트에 위치)
matcher: 인증 보호 경로 설정 (/
, /dashboard/:path*
등)
동작:
/
또는 /dashboard
등 보호된 페이지 접근refreshToken
확인/login
으로 리다이렉트예시 코드:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(req: NextRequest) {
const token = req.cookies.get("refreshToken");
const { pathname } = req.nextUrl;
if (pathname.startsWith("/login")) return NextResponse.next();
if (!token) {
const loginUrl = req.nextUrl.clone();
loginUrl.pathname = "/login";
return NextResponse.redirect(loginUrl);
}
return NextResponse.next();
}
export const config = {
matcher: ["/", "/dashboard/:path*"],
};