개발자

Next14 SSR 과정에서 Authorization에 쿠키를 사용해 토큰값을 전달하면 에러가 발생합니다..

2024년 02월 08일조회 1,058

안녕하세요. 혼자서 해결해 보려고 했지만, 오랜 시간 해결하지 못해 지푸라기라도 잡는 심정으로 질문 올려봅니다.. 기존에 localstorage를 사용해 fetch로 데이터를 요청했으나 SSR 과정에서 window 사용이 불가능하기 때문에 쿠키를 사용을 계획했습니다. 로그인 -> 쿠키에 토큰값 저장 -> 데이터 요청 시 쿠키에서 토큰 값을 꺼내고 헤더 Authorization에 담아 SSR에서도 사용하려고 했습니다. next에 내장되어있는 'next/headers'가 아닌 'cookies-next'를 사용하고 있습니다. <문제 상황> 처음에는 토큰 유효 기간이 지났다(토큰 값이 들어오지 않았다)는 에러가 발생하고 곧이어 데이터를 정상적으로 받아옵니다 (제 추측으로는 SSR 과정에서 토큰 값을 인식하지 못하고 에러가 발생하고 클라이언트 단에서는 쿠키 값을 정상적으로 반영해 데이터 페칭이 진행된 것 같습니다.) <질문> 1. Suspense를 적용하지 않을 경우 에러 없이 동작하지만 next streaming이 적용되지 않습니다.. 그리고 getCookie를 통해 가져온 값이 SSR 시 적용되지 않는 이유가 궁금합니다! 2. 현재 쿠키를 사용해 SSR 시 토큰 값을 전달하려는 방법이 최선의 방법이 맞는지 궁금합니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 1

김태우님의 프로필 사진

지금 토큰을 쿠키에 설정하는 부분이 클라이언트 측인데 이렇게 해주는 이유가 있을까요? 일반적으로 로그인 로직은 사용자 아이디 비번 입력 -> 요청 -> 검증 -> 토큰 생성 -> 응답 간단히 이런 식으로 돼서 서버에서 응답헤더에 쿠키를 설정해 쿠키에 토큰을 담습니다. 현재 오류가 나는 부분도 클라이언트 측에서 쿠키를 설정하는 부분 때문에 발생하는 거 같아요. 쿠키를 설정하는 컴포넌트는 클라이언트 컴포넌트이고 로그인 요청을 보내는 부분은 서버 컴포넌트이기 때문에 쿠키를 설정하기도 전에 요청이 가버려서 에러가 발생하는 거 같습니다.

박하민님의 프로필 사진

박하민

작성자

취준생2024년 02월 09일

안녕하세요! 답변 감사합니다. 현재 소셜 로그인 시 쿼리 파라미터를 사용해서 토큰 값을 저장하고 리뷰 목록을 조회하기 위해 백엔드 서버에 데이터 요청할 때 Authorization: `Bearer ${accessToken}`으로 토큰을 담아서 보내야 하는 상황입니다. 'next/headers'를 사용해서 따로 util 파일을 만들었을 때에도 에러가 발생해서 cookies-'next'를 사용하게 되었습니다. 쿠키를 사용한 이유는 서버에서 쿼리 파라미터의 값을 저장하고(localstorage 사용 불가) API 요청 시 사용하는 목적으로 사용을 계획하고 있었습니다! 그런데 위의 코드가 SSR 시 쿠키에서 꺼낸 값을 인식하지 못하는 것 같습니다..

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

소셜 로그인이라면 리다이렉트 시에 access 토큰 말고 인가코드를 쿼리 파라미터로 받고 그 인가코드를 서버로 넘겨줘서 서버에서 소셜로그인 측으로 access 토큰을 받는 방식을 주로 사용하는 것으로 알고 있는데 어떤 소셜 로그인인가요?

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

OAuth 프로토콜 방식에서 클라이언트에서 직접 access 토큰을 받게 되면 브라우저 URI에 바로 노출되는 문제가 있어 위와 같은 방식으로 인가 코드를 받고 바로 노출되지 않게 서버에서 인가 코드를 통해 access 토큰을 받는 방식을 사용합니다!

박하민님의 프로필 사진

박하민

작성자

취준생2024년 02월 09일

현재 카카오 소셜로그인을 사용하고 있습니다! 백엔드에서 쿼리 파라미터 방식을 제안하셔서 말씀해 주신 방법은 사용하지 않고 있는 상태입니다!

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

만약 저 방법대로 하신다면 Next.js 서버 컴포넌트에서도 쿼리 마라미터를 Page Props로 받을 수 있습니다. Props 객체 안에 searchParams라는 속성이 있습니다. 따라서 데이터 페칭하는 함수에서 이 값을 매개변수로 받도록 하면 따로 브라우저 저장소에 저장하지 않아도 될 거 같습니다!

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

리다이렉트 된 uri에 access_token 키 값으로 저장되어 있을 텐데 export default async function Page({searchParams}) const datafetching = getData(searchParams.access_token); 이런 방식으로 해보시는 건 어떨까요?

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

이렇게 되면 처음 로그인할 때 서버에서 쿠키에 토큰을 저장하고 리뷰 데이터를 받을 때에도 따로 클라이언트 측에서 처리하지 않고 서버에서 쿠키에 토큰이 있는지 없는지 확인 후 데이터를 내려주는 방식이 될 거 같습니다.

김태우님의 프로필 사진

김태우

zzambbong developer2024년 02월 09일

만약 액세스토큰을 꼭 클라이언트에서 쿠키에 저장하고 싶으시면 14버전부터 클라이언트에서 서버 액션을 할 수 있습니다. 서버 액션을 하는 함수를 따로 빼서 페이지에서 받아온 쿼리 파라미터를 넘겨주시는 방법도 있을 거 같네요. 다음은 해당 내용에 대한 공식문서 내용입니다. https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#cookies

박하민님의 프로필 사진

박하민

작성자

취준생2024년 02월 09일

좋은 정보 감사합니다! 최대한 반영해 보려고 했으나 마음처럼 잘 안되네요.. 말씀해 주신 부분처럼 searchParams를 사용했을 때 해당 페이지에서 uri에 있는 accessToken을 저장할 수 있지만, 다른 페이지에 이동해서 accessToken을 사용하기 위해서 localstorage와 쿠키에 값을 저장하려고 했습니다. 클라이언트 컴포넌트에서 현재 코드를 호출해서 사용하고 있었습니다. react-query 로직이 포함되어 있어 'use server' 키워드를 사용할 수 없었고 'next/headers'를 따로 util 파일로 만들어 호출해서 사용하게 되었습니다. 쿠키를 꺼내서 Bearer 토큰에 값을 포함해 사용해 보려고 했으나 다른 에러가 발생하게 되네요.. 😭 Uncaught Error: Server Functions cannot be called during initial render. This would create a fetch waterfall. Try to use a Server Component to pass data to Client Components instead. Cannot update a component (`Router`) while rendering a different component (`ReviewSection`). To locate the bad setState() call inside `ReviewSection`, follow the stack trace as described in 에러를 살펴보니, const accessToken = getCookie('accessToken') 유틸 파일에서 호출한 next/headers 쿠키 값을 꺼내는 과정에서 에러가 발생하는 것 같습니다. 이 부분을 해결하기 위해 노력해 봐야겠네요..!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!