우선 실습을 진행하기 위해, 로그인이 되어 있을떄, cookie의 값이 어떤것이 있는지 확인을 해 보겠습니다.
이전에 iron-session에서 설정해둔 carrotsession이 잘 저장되어 있는 것을 보실 수 있습니다.
그래서 미들웨어 측면에서 cookie가 없다면 NextResponse를 이용해서 /enter로 redirect시켜보도록 했습니다.
/pages/_middleware.ts
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(
req: NextRequest,
ev: NextFetchEvent
) {
if (req.ua?.isBot) {
return new Response("Plz don't be a bot. Be human", {
status: 403,
});
}
if (!req.cookies.carrotsession) {
return NextResponse.redirect("localhost:3000/enter");
}
}
브라우저의 secret모드로 들어가면 이는 "localhost redirected you to many times"이라는 오류를 뱉게 됩니다. 이 이유는 /enter로 redirect시켜지면, 또 미들웨어가 실행되고 또 redirect가 반복되는 것이 무한히 반복되기 때문입니다.
이 오류는 해당 미들웨어를 요청한 req.url이 /enter가 아닐때만 redirect시켜주면 됩니다. 그럼 이러한 재귀적인 상황을 막을 수 있습니다.
/pages/_middleware.ts
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(
req: NextRequest,
ev: NextFetchEvent
) {
if (req.ua?.isBot) {
return new Response("Plz don't be a bot. Be human", {
status: 403,
});
}
console.log(req.url);
if (
!req.url.includes("/enter") &&
!req.cookies.carrotsession
) {
return NextResponse.redirect("http://localhost:3000/enter");
}
}
잘 동작하는 것을 확인할 수 있습니다.
또한 이전에도 말했다 싶이 미들웨어는 /api즉 Next의 api핸들러에도 적용됩니다. 만약 로그인을 하려고 /api/users/confirm이런거에 POST요청을 보냈다고 해 봅시다. 그런데 이떄는 쿠키가 아직 적용되기 전이니까 redirection될 겁니다. 그래서 아래와같이 이를 보호해주는 코드를 작성해 주어야 합니다.
/pages/_middleware.ts
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(
req: NextRequest,
ev: NextFetchEvent
) {
if (req.ua?.isBot) {
return new Response("Plz don't be a bot. Be human", {
status: 403,
});
}
if (!req.url.includes("/api")) {
if (
!req.url.includes("/enter") &&
!req.cookies.carrotsession
) {
return NextResponse.redirect(
"http://localhost:3000/enter"
);
}
}
}
또한 req에는 geo정보 즉 현재 사용자의 위치도 알려줍니다. 다만 지금은 Localhost에서 사용중인데, 이 geo는 호스팅업체로부터 정보를 받아오므로, 지금은 확인할 수 없고, 배포를 한 경우에 한해서만 사용할 수 있게 됩니다.
/pages/_middleware.ts
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(
req: NextRequest,
ev: NextFetchEvent
) {
if (req.ua?.isBot) {
return new Response("Plz don't be a bot. Be human", {
status: 403,
});
}
if (!req.url.includes("/api")) {
if (
!req.url.includes("/enter") &&
!req.cookies.carrotsession
) {
return NextResponse.redirect(
"http://localhost:3000/enter"
);
}
}
return NextResponse.json({ ok: true });
}
다음과 같이 마지막에 응답을 바로 찍어버릴 수 있습니다.
'Web > NextJs' 카테고리의 다른 글
[ Next.js - DeepDive ] - Lazy-load Imports (0) | 2022.08.04 |
---|---|
[ Next.js - DeepDive ] - Dynamic Import (0) | 2022.08.04 |
[ Next.js - DeepDive ] -미들웨어 ( Middlewares ) (0) | 2022.08.04 |
Next.js - _document와 _app에 대하여 (0) | 2022.03.30 |
Next.js - Advanced Custom app + next-redux-wrapper를 활용한 data pre-rendering (0) | 2022.03.03 |