Next.js)SSR환경에서의 Session방식 로그인과 Cookie

ynnsuis·2023년 7월 4일
0

최근 프로젝트에서 로그인 기능 구현을 세션id를 활용한 방식으로 진행했다. 이전에 구현했던 방법으로는 로컬스토리지를 활용한 JWT토큰으로 로그인하는 방식을 구현해봤는데, session 방식은 아무것도 아는게 없어서 클라이언트 단에서 http요청을 할때 어떤 설정을 해야하는지 초반부터 많이 헤맸다.

session방식을 공부하며 느낀 장점

세션방식의 장점으로는 인증정보를 서버에서 관리하여 보안적으로 우수하다. 인증정보를 가지고 있는 토큰과는 달리 session id를 보관하는 쿠키는 단순 문자열이라 탈취되어도 그 자체로는 의미가 없으며, 혹여나 탈취한 session id로 HTTP요청을 통해 해킹을 할수있기 때문에 HTTPS인증과 세션 만료를 설정하여 보안을 강화했다. 또한 클라이언트 단에서 아무런 설정을 하지않아도, 로그인시 자동으로 session id가 쿠키에 실려서 클라이언트단에서 인증 구현이 정말 편했다.

문제 : 서버단 HTTP 요청에 쿠키가 실리지 않음

문제는 SSR환경에서 쿠키를 활용해 유저정보를 받아오는 것이였다. 서버단에서 HTTP Request에 쿠키가 실리지 않아서 유저정보를 받아오지 못했다. 미리 렌더링하여 페이지를 보여주지 못하니, 새로고침을 하거나 마이페이지를 들어가면 클라이언트단에서 다시 요청한 유저데이터를 받아올때까지 헤더의 유저메뉴와 마이페이지의 프로필의 데이터 로딩시간이 많이 거슬렸다. 특히 개발 초기에는 백엔드 서버를 해외에있는 것으로 사용해서 더 그렇게 느꼈던것 같다.

구글링해서 찾아보니 Next.js 13이전버젼에서는 getInitialProps에서 ctx res 객체에서 cookie값을 받아와서 요청을 했었다고 하는데, Next.js 13버젼부터는 방식이 바뀌었다.

해결

결국 서버단에서 cookie를 활용하기위해 로그인시 쿠키에 따로 set하는 로직을 추가했다.

  /** auth 폼 제출 핸들러 */
  const onSubmit: SubmitHandler<FieldValues> = async (data) => {
    setIsLoading(true);
    try {
      const response = await axiosBase.post("users/login", data);
      const sessionId = response.data.session_id;
      Cookies.set("session-id", sessionId);

      const currentUser = await getCurrentUser();
      client.setQueryData(["currentUser"], currentUser);

      router.back();
      toast.success("로그인 되었습니다.");
    } catch (err: any) {
      const errorMessage = err?.response.data.detail;
      toast.error(errorMessage);
    } finally {
      setIsLoading(false);
    }
  };

하지만 클라이언트단에서 쿠키를 set 하고 get하는 js-cookie 라이브러리는 서버 컴포넌트에서 동작을 하지않았다.

공식문서를 찾아보니 Next.js 13버젼 app router 에서 지원하는 next/headers의 cookies라는 기능이 있었다.

import { cookies } from 'next/headers'
 
export default function Page() {
  const cookieStore = cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

이렇게 쿠키저장소에 있는 쿠키값을 읽어서 서버단에서 로그인 유저정보를 받아오는 요청을 할수 있게되었다.

해당 방법으로 이제 헤더의 유저메뉴 부분과 마이페이지도 SSR을 통해 로딩이나 리렌더링없이 바로 렌더링하여 사용자 경험을 향상시킬수 있었다.

다만 로그인시 session id를 쿠키저장소에 따로 set 하고 또 요청할때 get해서 하는 방식이 뭔가 매끄럽지 않은것 같다고 느꼈다. 다른방법이 있는지 추가적으로 공부를 해봐야겠다.

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

0개의 댓글