쿠키로 Access Token과 Refresh Token을 받아보자

YouGyoung·2024년 8월 7일
0

Next.js RSC

Next.js에서는 RSC(React Server Component)를 별도 설정 없이 간단하게 사용할 수가 있다.

'use client' 지시어만 컴포넌트 최상단에 추가하지 않으면 그 컴포넌트가 바로 서버 컴포넌트가 되기 때문이다.

이 점을 이용해 클라이언트에서 접근 가능한 로컬 스토리지가 아닌 서버에서만 접근 가능한 쿠키를 통해 Access Token과 Refresh Token을 받아보자!

서버에서만 접근 가능한 쿠키?

자바스크립트에서 document.cookie을 사용하면 모든 쿠키를 확인할 수 있다.
즉, 클라이언트에서 쿠키를 확인할 수 있다.

클라이언트 측 스크립트에서 접근이 불가능하도록 하려면 쿠키를 설정할 때 httpOnly 속성을 ture로 설정해야 한다.

httpOnly 속성

httpOnly 속성은 웹 애플리케이션의 쿠키를 보다 안전하게 만들기 위해 사용된다.
httpOnly 속성이 true인 경우 클라이언트 측 스크립트에서 접근할 수 없기 때문에 XSS(Cross-Site Scripting) 공격을 예방할 수 있게 된다.

XSS(Cross-Site Scripting)
: 웹 페이지에 악성 스크립트를 넣어 사용자의 정보를 훔치거나 악성 행동을 하게 만드는 공격

CSRF 공격은?

httpOnly 속성만으로는 CSRF(Cross-Site Request Forgery) 공격은 예방하지 못 한다.

CSRF(Cross-Site Request Forgery)
: 웹 페이지에 사용자가 인증된 상태에서 의도치 않은 요청을 전송하도록 속이는 공격

CSRF 공격을 예방하기 위해 쿠키의 SameSite 속성을 Strict으로 설정할 수 있는데 백엔드 서버 도메인이 클라이언트 도메인과 다르면 쿠키가 전송되지 않아 인증 문제가 발생하게 된다.

백엔드와 클라이언트 도메인이 다른 경우에는 CSRF 토큰을 사용하거나 Referer 헤더 검증을 통해 CSRF 공격을 예방할 수 있다.

CSRF 토큰

CSRF 토큰은 각 요청에 대해 고유한 토큰을 생성하여 검증을 통해 CSRF 공격을 예방한다.

  1. CSRF 토큰은 서버에서 생성되어 클라이언트로 전달한다.
  2. 클라이언트는 서버에 요청 시 CSRF 토큰을 헤더에 포함해 요청한다.
  3. 서버는 요청에 대해 CSRF 토큰을 검증하고 요청에 대해 거부 또는 응답 처리한다.

CSRF 토큰은 헤더 말고 폼데이터에 직접적으로 포함하기도 하지만 GET 요청에는 적용하기 어려우므로 헤더에 CSRF 토큰을 설정하는 코드 구현이 추가적으로 필요하더라도 헤더에 넣는 것이 보안에도 좋다.

Referer 헤더 검증

Referer 헤더 검증은 요청 출처가 올바른지 확인하여 CSRF 공격을 예방한다.

  1. 서버에서 요청 Referer 헤더에서 요청이 발생한 페이지의 URL을 확인한다.
  2. Referer 헤더에서 값이 신뢰할 수 있는 도메인에서 온 요청인지 확인하고 요청에 대해 거부 또는 응답 처리한다.

Nest.js와 Next.js로 서비스 로그인 부분을 구현하면서 액세스 토큰과 리프레쉬 토큰을 어디에 저장하면 좋을지 고민했었다.

예전 프로젝트에서는 로컬 스토리지에 저장을 했었는데 클라이언트에서 접근 가능하니까 아무래도 보안에 취약하다 보니 이번 프로젝트에서는 쿠키에 저장하는 방식을 가져가게 되었다!

많은 설정에도 불구하고 쿠키가 탈취될 수도 있으니 클라이언트에서 요청할 때 액세스 토큰 쿠키만 요청 시에 보내도록 추가 설정(액세스 토큰 만료 시에는 리프레시 토큰으로 신규 액세스 토큰 요청)이 필요할 거 같다.

profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보