인프런 커뮤니티 질문&답변

ajrfyd님의 프로필 이미지
ajrfyd

작성한 질문수

한 입 크기로 잘라먹는 Next.js(15+)

3.4) 리액트 서버 컴포넌트 이해하기

client & server components 관련 질문입니다.

작성

·

108

0

완강 후 Next로 프로젝트를 만들어 보며 질문 드립니다.

제가 쿠키를 활용할 일이 있어 Nest api 요청에 쿠키를 담아 보냈었습니다. 쿠키가 잘 도착 하는 상황은

  1. postman요청,

  2. 브라우저에서 nest api 직접 요청

Next 페이지 에서는 쿠키가 도착하지 않았습니다.

완강 후 Next에서는 최대한 static하게 만들면서도 동적으로는 소통할 수 있도록 만드는 것이 Next가 추구하는 방향이라 이해 하였고, 최대한 static하게 만들었습니다.

쿠키가 도착하지 않아 한참을 실랑이를 하였는데 생각을 해 보니 서버컴포넌트에서 client로 cookie를 저장 한 다는 것이 말이 되지 않다는 것을 알았습니다. 찾아 보니 미들웨어라는 것이 있었고, 서버에서 쿠키를 내리는 것이 아니라 api응답을 받기 전 미들웨어에서 client에 쿠키를 심는 방법이 있더라구요. 근데 client에서 쿠키를 심더라도 static한 페이지로 만들어진 페이지에서 다음 요청에 쿠키를 서버로 전송하지 않기 때문에 쿠키를 활용해 서버와 뭔가의 소통이 불가능 하다고 느껴졌습니다.
제 질문이 이해가 가실지 모르겠지만..Next에서 보통 서버와 쿠키를 활용한 상호작용을 할때 어떤 방식을 통해 하는지궁금합니다.

 

답변 2

0

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

결론적으로 궁금하신 내용이 "Next.js 서버에서 쿠키를 어떻게 활용해야 하는지" 인 것인가요?! 그렇다면 다음과 같이 답변드릴 수 있을 것 같습니다.

우선 서버 컴포넌트에서는 쿠키의 값을 불러오는 것은 가능하나 쿠키의 값을 변경하는 것은 불가능합니다. 이는 Next.js가 막아둔 제한사항입니다. 자세한 사항은 다음의 문서를 참고하시면 좋겠습니다.

https://nextjs.org/docs/app/api-reference/functions/cookies

쿠키의 값은 오직 Router Handler(API Routes 입니다)나 서버액션 또는 미들웨어에서만 수정이 가능합니다. 따라서 보통은 미들웨어에서 쿠키를 처리하곤 하는데(인증 등의 데이터) 필요하다면 서버액션에서도 수정할 수 있습니다.

예를 들어 미들웨어에서는 로그인 되지 않은 사용자의 특정 페이지 접근을 막기 위해 쿠키를 사용하고, 서버액션에서는 로그인 액션이 수행되었을 때에 별도의 백엔드 서버로부터 받아온 인증 정보를 쿠키에 저장하도록 설정할 수 있습니다.

 

근데 client에서 쿠키를 심더라도 static한 페이지로 만들어진 페이지에서 다음 요청에 쿠키를 서버로 전송하지 않기 때문에 쿠키를 활용해 서버와 뭔가의 소통이 불가능 하다고 느껴졌습니다.

위 질문에 대해서는 제가 맥락을 잘 이해하지 못했습니다. 조금만 더 구체적으로 어떤 부분이 불가능하다고 느껴지셨는지 말씀해주시면 추가 답변드리겠습니다.

 

 

ajrfyd님의 프로필 이미지
ajrfyd
질문자

뭔가 많이 썼는데 핵심이 없는 느낌이네요ㅠ

일단 제가 해보고 싶언던 것은

보통의 express 와 react사이의 쿠키교환

  1. 랜더링시 react에서 api요청

  2. express에서는 api와 함께 쿠키 전송

  3. 받은 api 데이터를 활용 랜더링, 쿠키 저장

  4. 다음 요청에 받은 쿠키를 보냄

이런 과정이었습니다.

Next에서는 Nest 서버에서 보낸 쿠키 자체를 활용할 방법을 잘 모르겠어서 질문 드렸었습니다. api요청을 보낸 컴포넌트를 클라이언트 컴포넌트로 만들지 않는 한 서버에서 보낸 쿠키를 활용(client에서 만든게 아니고)할 수 있는 방법이 감이 오지 않아 질문드립니다.

Nest(express)에서 보낸 쿠키가 client를 거쳐 다시 Nest(express)로 오기 까지의 과정입니다.ㅠ

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

원하시는 상황이 그렇다면...

Next.js 서버측에서 페이지를 생성할 때에 Nest.js(헷갈리니 백엔드 서버라고 통칭할게요)로 부터 불러온 데이터를 쿠키 값으로 설정하고 싶으신건가요?

그렇다면 왜 이렇게 동작해야 하는건가요? 일반적으로 자주 사용되는 패턴은 아닌 것으로 보이는데 ... 기능 구현의 목적이 무엇인지 궁금합니다 🤔 상황을 구체적으로 알게되면 다른 방향의 구현도 제안드릴 수 있을 것 같아요

우선 해당 상황에 입각해서만 답변드리자면 앞서 말씀드렸듯이 서버컴포넌트에서는 쿠키값을 설정할 수 없기 때문에 미들웨어를 활용하셔야 합니다.

ajrfyd님의 프로필 이미지
ajrfyd
질문자

아 일단 해보고 싶은 것은 쿠키로 방문 여부 체크 기능 입니다. 메인 화면 혹은 게시글 카운트를 위해 서버에서 24시까지 남은 시간을 만료 시간으로 설정 한 뒤 사용 하는 것입니다.

일반적이지 않은 방법일까요?? 방문자 체크나 팝업의 체크 여부 등등 기능을 구현할때 이런 방식을 활용되지 않나요???

물론 클라이언트 사이드에서도 쿠키를 심을 수 있긴 하지만 저의 의도는 클라이언트에서 쿠키는 의도적으로 심을 수 있을것 같아(위조?) 서버에서 심는 방법을 시도하였습니다.

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

그렇다면 방문정보를 쿠키 값으로 설정하는 Route Handler(API Routes)를 만드신 다음

// app/api/set-cookie/route.ts

import { NextResponse } from 'next/server';

export async function GET() {
  const currentDate = new Date();
  const expireDate = new Date(currentDate);
  
  // 24시간 뒤 만료
  expireDate.setHours(currentDate.getHours() + (24 - currentDate.getHours()));

  // 쿠키 설정
  const response = NextResponse.json({ message: 'Cookie set successfully!' });

  // 헤더에 쿠키를 추가
  response.cookies.set('visited', 'true', {
    path: '/',
    expires: expireDate,
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
  });

  return response;
}

클라이언트 사이드에서 useEffect를 사용해 페이지가 마운트 되자마자 해당 API를 호출하시는걸 추천드립니다.

import { useEffect } from 'react';

export default function Home() {
  useEffect(() => {
    fetch('/api/set-cookie');  // 방문할 때마다 쿠키 설정
  }, []);

  return (
    <div>
      <h1>홈 페이지</h1>
    </div>
  );
}

이렇게 되면 방문 여부 체크는 문제 없이 가능합니다. 보안적인 측면에서도 HttpOnlySecure와 같은 속성을 사용하여 자바스크립트로 접근하지 못하도록 하고 HTTPS를 통해서만 전송되도록 설정했으므로 문제 없어보입니다.

0

안녕하세요, 인프런 AI 인턴입니다. ajrfyd님.

Next.js에서 서버와의 쿠키 상호작용에 대한 질문을 주셨네요. 비슷한 주제의 질문들에 대해 이미 답변된 자료들이 있어서 이를 통해 힌트를 얻으실 수 있을 것입니다.

관련 주제에 대한 몇 가지 유사한 답변을 안내해 드리겠습니다.

  1. Next.js: 클라이언트와 서버 간 쿠키 연동 문제 해결하기:
    이 게시글에서는 Next.js에서 클라이언트와 서버 간 쿠키 사용 문제를 해결하는 방법을 다룹니다. 특히, 서버와 클라이언트 간의 쿠키 전달 및 인증 관련 설정을 설명합니다.

  2. SSR과 쿠키 사용 예제:
    서버 사이드 렌더링(SSR)을 이용한 쿠키 설정 및 처리 방법에 대한 예제 코드를 제공합니다. SSR을 사용하여 Next.js 앱에서 쿠키를 처리하는 일반적인 방법을 참조할 수 있습니다.

  3. 서버 컴포넌트와 클라이언트 컴포넌트에서 쿠키 관리:
    서버 컴포넌트와 클라이언트 컴포넌트가 어떻게 쿠키를 관리하고 이를 활용할 수 있는지에 대해 설명합니다.

간단한 요약

Next.js에서 쿠키를 활용한 서버와의 상호작용은 다음과 같은 단계로 이뤄질 수 있습니다:

  1. 서버 사이드에서 쿠키 설정:

    • Next.js의 getServerSideProps 혹은 API Routes를 사용하여 초기 요청에서 서버가 쿠키를 설정하도록 합니다.
  2. 클라이언트 사이드에서 쿠키 접근:

    • 클라이언트 사이드에서는 js-cookie 등의 라이브러리를 사용하여 설정된 쿠키를 가져오거나 설정할 수 있습니다.
  3. 미들웨어 활용:

    • Next.js의 미들웨어를 사용하여 요청을 처리하기 전에 쿠키를 설정하거나 검증할 수 있습니다.

아래 샘플 코드를 참고하세요:

// pages/api/login.js
import cookie from 'cookie';

export default function handler(req, res) {
  if (req.method === 'POST') {
    res.setHeader('Set-Cookie', cookie.serialize('token', String(req.body.token), {
      httpOnly: true,
      secure: process.env.NODE_ENV !== 'development',
      maxAge: 60 * 60,
      sameSite: 'strict',
      path: '/'
    }));
    res.statusCode = 200;
    res.json({ success: true });
  } else {
    res.statusCode = 405;
    res.end();
  }
}
// pages/dashboard.js
import { useEffect } from 'react';
import cookie from 'js-cookie';

export async function getServerSideProps(context) {
  const cookies = cookie.parse(context.req.headers.cookie || '');
  const token = cookies.token;
  
  if (!token) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  // Further server-side operations
  return { props: {} };
}

function Dashboard() {
  useEffect(() => {
    // Additional client-side operations
  }, []);

  return (
    <div>Dashboard</div>
  );
}

export default Dashboard;

이 방법들을 통해 서버와 클라이언트 간에 쿠키를 활용한 상호작용을 원활히 진행할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

ajrfyd님의 프로필 이미지
ajrfyd

작성한 질문수

질문하기