시작하며...
게시물 수정 페이지 같은 경우 해당 게시글을 작성한 사용자만 수정이 가능하다.
그래서 작성자에게만 수정 버튼이 렌더링 되지만 만약 그렇지 않은 사용자가 주소창을 통해 강제로 수정 페이지로 이동하였을 때, 해당 게시글의 작성자가 아니면 접근을 하지 못하게 막아야 된다.
Next.js Server Side Rendering 에서 이를 구현하는 방법에 대해 알아볼 것이다.
구현 방식
현재 로그인한 유저의 user id 와 게시물을 작성한 user id 를 비교해서, 다르면 not found 페이지로 이동시킨다.
로컬 스토리지
서버 사이드 렌더링은 서버에서 페이지를 렌더링하며, 브라우저 API 인 document, window 등 객체에 접근할 수 없다.
그래서 로컬 스토리지 같은 경우 브라우저에서 window 객체를 통해 접근할 수 있어, user id 를 로컬 스토리지에 저장하면 서버에서 해당 값에 접근할 수 없게 된다.
쿠키
반면 쿠키는 HTTP 요청의 헤더를 통해 서버와 클라이언트 간에 자동으로 전송된다.
그래서 Server Side Rendering 과정에서 서버는 HTTP 요청에 포함된 쿠키 정보를 읽을 수 있게 된다.
구현하기
1. 쿠키 저장하기
next 의 Server Side 에서 쿠키를 읽고 설정할 수 있는 cookies
API 를 가져온다.
import { cookies } from "next/headers";
그리고 로그인이 성공하고, 응답으로 온 user 의 id 값을 쿠키에 저장을 한다.
cookies().set("userId", data.user.id);
2. 게시물 정보 API
게시물을 수정하기 위해 수정할 게시물의 정보를 가져오는 API 요청을 한다.
호출 결과는 res 변수에 저장하였다.
const res = await getBoardDetailData(boardId);
3. 쿠키 가져오기
현재 로그인한 유저의 user id 를 쿠키에서 가져온다.
const userId = cookies().get("userId")?.value;
4. 권한 확인
게시물의 작성자와 현재 로그인한 유저를 비교하여 일치하지 않을 경우 /not-found
페이지로 리다이렉트 하였다.
if (res.writer.id !== Number(userId)) {
return redirect("/not-found");
}
CSR 같은 경우는 데이터를 가져오면서 로딩화면이 보였다가 리다이렉트 되기 때문에 사용자 경험 측면에서 좋지 않지만,
SSR 에서 컴포넌트가 화면에 렌더링 되기 전에 서버에서 미리 권한을 확인하고 리다이렉트 되기 때문에 사용자 경험성이 좋다.
전체 코드
const EditBoardPage = async ({ params }: { params: { boardId: number } }) => {
const { boardId } = params;
const userId = cookies().get("userId")?.value;
try {
const res = await getBoardDetailData(boardId);
if (res.writer.id !== Number(userId)) {
return redirect("/not-found");
}
const parsedContent = JSON.parse(res.content);
const initialData: BoardAddEditInput = {
title: res.title,
content: {
content: parsedContent.content,
token: parsedContent.token,
},
...(res.image && { image: res.image }),
};
return <EditBoardForm initialData={initialData} boardId={boardId} />;
} catch (error) {
return redirect("/error");
}
};
마치며...
대단한 내용은 아니지만 Next.js Server Side Rendering 은 서버에서 렌더링 하는 것이며 클라이언트엔 접근이 불가능하다는 것을 제대로 알게 되었다.
'💜 리액트 > Next.js' 카테고리의 다른 글
[Next.js] 채널톡 연동하기 구현 (feat. app router, typescript) (1) | 2024.08.28 |
---|---|
[Next.js / TanStack Query] Server Side Rendering 하기 (feat. app router) (0) | 2024.08.27 |
[Next.js] 메타태그, 오픈그래프 컴포넌트 SEO 향상 (feat. Page Router) (0) | 2024.07.12 |
[Next.js] Framer Motion 화면 전환 애니메이션 적용 (feat. Page Router) (2) | 2024.07.10 |
[Next.js] Zustand persist 사용하기 (feat. Hydration 에러 해결) (1) | 2024.07.01 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!