Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
import { isTokenExpired } from "@/utils/jwtUtils";

const loginNeedPages = ["/mentor", "/my", "/community"]; // 로그인 필요페이지
const NEED_LOGIN_COOKIE_KEY = "isNeedLogin";
Expand All @@ -15,6 +14,7 @@ const blockedExactPaths = new Set([
const blockedPathPrefixes = ["/wp-admin", "/phpmyadmin", "/pma", "/.env", "/.git", "/vendor"];

const isStageHostname = (hostname: string) => hostname.includes("stage");
const isLocalHostname = (hostname: string) => hostname === "localhost" || hostname === "127.0.0.1";

const isProbePath = (pathname: string) => {
if (blockedExactPaths.has(pathname)) {
Expand Down Expand Up @@ -84,10 +84,10 @@ export function middleware(request: NextRequest) {
});
}

// localhost 환경에서는 미들웨어 적용 X
// if (url.hostname === "localhost") {
// return NextResponse.next();
// }
// local 개발 환경에서는 서버 도메인 쿠키와 분리되어 refreshToken을 신뢰할 수 없으므로 로그인 가드를 스킵한다.
if (isLocalHostname(request.nextUrl.hostname)) {
return NextResponse.next();
}

// HTTP-only 쿠키의 refreshToken 확인
const refreshToken = request.cookies.get("refreshToken")?.value;
Expand All @@ -101,10 +101,6 @@ export function middleware(request: NextRequest) {
return buildLoginRedirectResponse(request);
}

if (needLogin && isTokenExpired(refreshToken ?? null)) {
return buildLoginRedirectResponse(request, { clearRefreshToken: true });
}

return NextResponse.next();
Comment on lines 101 to 104
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reinstate refresh-token expiry guard on login-required paths

With this change, /mentor, /my, and /community only check whether refreshToken exists, and no longer validate expiration before allowing the request through. In stage/prod, a user with an expired but still-present cookie now bypasses the middleware redirect and reaches protected pages until downstream API calls fail, and the cookie-clearing path is never executed. This is a regression from the previous behavior where expired refresh tokens were redirected to /login immediately.

Useful? React with 👍 / 👎.

}
export const config = {
Expand Down
Loading