본문 바로가기
source-code/Next JS

[next js] server component로 httpOnly cookie 접근하기

by mattew4483 2024. 2. 6.
728x90
반응형

현재 저희 서비스는

1) next 14로 구성한 admin 페이지에서 로그인

2) 로그인을 통해 access token, refresh token 발급

3) extension 내 API 요청 시 발급받은 access token을 함께 전달

위 flow를 통해 사용자를 인증하고, 적절한 권한을 부여하고 있습니다.

 

admin 페이지에서 로그인 성공 시 발급받는 token들은 모두 cookie에 저장되어 있는데,

이 경우 3) extension에서 API 요청 시 token 전달을 구현하기가 불가능하다는 문제가 있었습니다.

 

그 이유로는

extension을 사용 중인(요청이 보내지는) 페이지 도메인과 cookie를 발급받은 서버 도메인이 다를 수밖에 없기 때문입니다.

extension을 켜둔 상태로, 사용자가 원하는 웹 페이지에서 api 요청이 이뤄지기 때문에

samesite Strict 옵션의 cookie 사용 시, 브라우저는 해당 cookie를 함께 전송하지 않습니다.

 

물론 cookie 옵션을 samesite=None 하면 되지만

https://blog.google/intl/ko-kr/company-news/technology/privacy-sandbox-1percent-kr/

 

크롬에서 서드 파티 쿠키를 폐기하기 위한 다음 단계

웹 상에서 개인 정보 보호를 개선하는 작업은 절대 끝이 없습니다. 이에 크롬(Chrome)에서는 이용자들의 데이터를 보호하고 통제권을 강화할 수 있는 새로운 기능들에 계속해서 투자하고 있습니

blog.google

goole에 절대적인 영향을 받는 chrome extension에서는 사용할 수 없다 판단했습니다.

 

따라서 이를 해결하기 위해

1) admin 페이지에서 로그인을 통해 token 발급 시 → Cookie에서 token을 조회해 extension에 전달

2) extension의 API request는 header의 Authorization 값을 통해 인증 (admin에서 전달받은 token 사용)

형태로 변경하고자 했습니다.

 

HttpOnly Cookie 

일반적으로 Cookie 설정 시 XSS 공격 방지를 위해 HttpOnly 속성을 부여합니다.

→ 이를 통해 client script가 Cookie에 접근하는 것을 방지할 수 있습니다.

 

하지만 이를 반대로 생각하면...

client 측에서 HttpOnlyl cookie를 조회할 방법이 없음을 알 수 있습니다!

const ClientComponent = () => {
  const token = document.cookie; // httpOnly인 cookie 조회 불가
  return <p>토큰 : {token}</p>;
};

client component만 존재한다면, httpOnly cookie를 조회할 수 없겠죠!

 

Next JS 14 Server Component에서 Cookie 조회하기

Next 13 버전부터, app 디렉터리의 모든 컴포넌트들은 기본적으로 server component입니다.

// /app/home/page.tsx

/** @title 로그인 후 redirect된 페이지 */
const page = (data: any) => {
  return (
    <div>
    </div>
  );
};

따라서 Cookie 옵션이 HttpOnly라도, 해당 cookie에 접근할 수 있습니다!

 

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

 

Functions: cookies | Next.js

API Reference for the cookies function.

nextjs.org

공식 문서에서 제공하는 next/headers의 cookies 함수를 사용하면 됩니다.

 

import React from "react";
import { cookies } from "next/headers";

/** @title 로그인 후 redirect된 페이지 */
const page = () => {
  const cookieStore = cookies();
  const token = cookieStore.get("x-access-token")?.value;

  if (!token) {
    // token
    return null;
  }

  return (
    <div>
      <h1>토큰</h1>
      {token}
    </div>
  );
};

 

 

위와 같이 작성한 경우, 로그인 완료 후 cookie에 x-access-token이 저장되어 있다면...

해당 값을 조회해 사용할 수 있는 것이죠!

 

next/headers

그렇다면, next/headers를 통해 client component에서도 cookie에 접근할 수 있는 걸까요?

"use client"; // client component

import React from "react";
import { cookies } from "next/headers";
import ChromeStore from "@/components/admin/ChromeStore";

/** @title 로그인 후 redirect된 페이지 */
const page = () => {
    const cookieStore = cookies();
    const token = cookieStore.get("x-access-token")?.value;
}

client component에서 cookies 함수를 호출하면

 

아하..! 위와 같이 next/headers Server Component에서만 동작한다는 에러가 발생합니다.

 

server component로 httpOnly cookie 접근하기

server component를 사용하는 경우, 일반적인 웹개발에서는 불가능했던 작업들이 가능한 경우가 왕왕 있습니다.

대표적인 예시가 위와 같이, client에서도 HttpOnly option의 cookie 값에 접근할 수 있다는 것이죠.

/** @title 로그인 후 redirect된 페이지 */
const page = () => {
  const cookieStore = cookies();
  const token = cookieStore.get("x-onbording-access-token")?.value;

  if (!token) {
    // token
    return null;
  }

  return (
    <div>
      <h1>토큰</h1>
      <ClientComponent token={token}/>
    </div>
  );
};

const ClientComponent = ({token}:{token:string}) => {
	return <p>토큰 : {token} </p>
}

즉 해당 값을 Javascript 상태로 관리해, client component까지 내려줄 수도 있는 것이죠!

 

 

728x90
반응형