스터디

관리전략 blog

콩쥐땃쥐 2024. 12. 9. 05:40

Access Token & Refresh Token

Access Token?

Access Token은 사용자나 컴퓨터 프로그램이 접근할 권리를 증명하는데 사용되는 문자열이며, 일반적으로 인터넷에서 사용자 인증 및 권한 부여를 위해 주로 사용된다. 예들 들어, 소셜 미디어 플랫폼이나 웹 애플리케이션에서 사용자가 로그인할 때, 서버는 사용자의 인증 정보를 확인한 후 엑세스 토큰을 발급한다. 그리고 사용자가 이후 서비스를 이용할 때마다 이 토큰을 사용하여 자신의 인증 상태를 증명하게 된다. 

 

Access Token은 사용자가 인중 과정을 성공적으로 마친 후, 리소스에 접근할 수 있는 권한을 부여받기 위해 사용되는 Token값이다.

Refresh Token은 왜 필요할까?

Acess Token만을 통한 인증 방식의 문제는 제 3자에게 탈취당할 경우 보안에 취약하다는 단점이 있다.

Acess Token은 발급된 이후 서버에 저장되지 않고 토큰 자체로 검증을 하며 사용자 권한을 인증하기 대문에 Acess Token이 탈취되면 토큰을 획득한 누구나 권한에 접근이 가능해지기 때문이다.

 

JWT는 발급하면 삭제가 불가능하다. 따라서 접근에 관여하는 토큰에 유효시간을 부여하는 식으로 위의 문제에 대응하는 것이다.

이처럼 토큰 유효기간을 짧게 하면 토큰 남용을 방지할 수 있지만, 그만큼 사용자는 로그인을 자주 해야하기 때문에 불편하다는 단점이 있다. 

 

이를 보완해 유효기간을 짧게 하면서 할 수 있는 좋은 방법이 Refresh Token인 것이다.

Refresh Token이란?

Refresh Token은 Acess Token과 똑같은 JWT지만, Acess Token은 접근에 관여하는 토큰이고 Refresh Token은 재발급에 관여한다는 점에서 다르다.

 

Refresh Token은 긴 유효기간을 가지면서 Acess Token이 만료됐을 때 새로 재발급해주는 열쇠가 된다. 

원리는 만일 만료된 Acess Token을 서버에 보내면, 서버는 같이 보내진 Refresh Token을 DB에 있는 것과 비교해 일치하면 Acess Token을 다시 재발급해주는 것이다. 그리고 사용자가 로그아웃을 하면 저장소에서 Refresh Token을 삭제하여 사용이 불가능하도록 하고 새로 로그인하면 서버에서 다시 재발급해서 DB에 저장하는 것이다.

Refresh Token 인증과정

쿠키? 세션? 토큰?

앞서 Refresh Token을 살펴봤는데, 쿠키, 세션, 토큰이 무엇인지 헷갈릴 수 있다.

그래서 정리해본다.

 

브라우저에 저장되는 정보: 쿠키

쿠키는 크롬이나 사파리같은 브라우저에 저장되는 작은 텍스트 조각이다. 

사용자는 브라우저의 설정 화면이나 개발자 도구에서 쿠키를 확인하고 수정, 삭제할 수 있다. 다만 쿠키는 당사자뿐만 아니라 제 3자가 조회하는 것도 가능하기 때문에 개인 정보를 담은 내용이나 보안상 민감한 정보를 저장하는 데에는 적합하지 않다.

따라서 남에게 탈취되거나 사용자에 의해 조작되어도 크게 문제되지 않을 정보를 브라우저에 저장함으로써 웹사이트 이용을 편리하게 해주는 것이다.

 

서버가 나를 알아보는 방법: 세션

서버는 아이디와 비밀번호를 입력해 로그인에 성공한 사용자와 로그인한 다음 마이페이지 버튼을 누른 사용자가 동일 인물임을 알지 못한다. 그렇기 때문에 사용자가 사이트에 로그인한 상태라는 점을 서버에 인증하지 못하면 클릭을 할 때마다 반복해서 아이디와 비밀번호를 서버에 제공해야한다. 이런 번거로움을 해결하기 위해 사용하는 것이 바로 세션이다.

 

세션은 로그인 여부 등 사용자와 서버의 관계가 기억되어 보존되고 있는 상태를 말한다.

 

사용자가 사이트에 한 번 로그인하면 유효기간이 끝날 때까지 더 이상 아이디와 비밀번호를 입력하지 않아도 되도록 사용자가 이미 서버로부터 인증받았음을 증명해 주는 세션이라는 증서가 필요하다. 서버는 영화관에서 티켓을 보관용 부분만 건네주듯 세션 아이디를 사용자에게 전달하고, 메모리에 아이디 사본을 어떤 사용자의 것인지 적어서 보관한다.

사용자는 서버로부터 받은 세션 아이디를 쿠키로 저장한 다음 앞으로의 모든 요청에 함께 전달한다.

서버는 사용자에게서 목록을 보겠다는 요청을 받으면 세션 아이디가 적혀있는지 확인한다. 아이디가 있다면 서버가 보관하고 있는 세션 아이디 중에 동일한 정보가 있는지 찾아보고 그것이 누구의 계정인지 알아낸다. 그렇게 편지를 보낸 사람이 누군인지 파악한 다음 해당 사용자의 목록을 보내주는 것이다.

 

세션과는 또 다른 로그인 유지 방식:토큰

세션은 안전하고 효과적이지만 단점도 있다. 서버는 메모리에 올려둔 데이터를 빠르게 확인할 수 있지만, 공간이 한정돼 있다. 그래서 서버에 동시 접속하는 사용자가 많아지면 메모리 공간이 부족해져서 서버에 과부하가 걸리고 화면이 움직이지 않는 등의 문제가 발생할 수 있다.

 

메모리 공간을 많이 차지하는 세션 방식의 대안은 로그인한 사용자에게 세션 아이디 대신 토큰을 발급해 주는 것이다. 이러한 토큰에는 특수한 수학적 원리가 적용되어 있어서 마치 위조 방지 장치가 있는 지폐처럼 서버만이 유효한 토큰을 발행할 수 있다.

그렇기 때문에 토큰을 받아간 사용자가 이를 쿠키로 저장해 두고 필요할 때마다 제시하면 서버는 확인할 필요 없이 본인이 발급한 토큰임을 알아보고 사용자의 요청을 허가해 주는 것이다. 이미 로그인한 사용자를 메모리에 올려두고 있을 필요가 없기 때문에 이를 통해 서버 부하를 줄일 수 있는 것이다.

  세션 방식 토큰 방식
장점 사용자의 상태를 원하는대로 통제 가능 상태를 따로 기억해 둘 필요가 없음
단점 메모리에 로그인되어 있는 사용자의 상태를 보관해야 함 한 번 로그인한 사용자의 상태의 토큰

 

출처 : https://hongong.hanbit.co.kr/완벽-정리-쿠키-세션-토큰


token은 어디에 저장해야 안전한가?

토큰을 저장할 수 있는 방식 중 대표적으로는 비공개 변수, 로컬 스토리지, 세션 스토리지, 쿠키로 분류할 수 있다.

 

비공개 변수

비공개 변수의 경우 브라우저가 새로고침될 때마다 유지가 되지 않기 때문에 사용자는 새로고침 할 때마다 재접속을 해야하는 불편함을 감수해야한다.

 

로컬 스토리지+세션 스토리지(공통)

쿠키 방식과 다른 점

  1. 쿠키와 다르게 네트워크 요청 시 서버로 전송되지 않으며 쿠키보다 더 많은 자료를 보관할 수 있다.
  2. 서버가 HTTP 헤더를 통해 스토리지 객체를 조작할 수 없다.
  3. 웹 스토리지 객체는 도메인/프로토콜/포트로 정의되는 origin에 묶여있다. 다른 도메인에서 접근 시 CORS 에러가 발생하게 된다.

로컬 스토리지는 브라우저가 새로고침되더라도 정보들이 유지되기 때문에 사용자 편의성이 높은 편이며 브라우저를 닫아도 정보들이 유지된다. 다만 JS코드를 통해 접근이 가능하기 때문에 XSS공격에는 취약하고 CSRF 공격에는 안전하다.

- XSS공격 : 

- CSRF 공격 : 

 

세션 스토리지는 로컬 스토리지에 비해 제한적이다. 현재 떠 있는 탭에서만 유지되는 특징을 가진다. 새로 고침할 때는 사라지지 않지만, 탭을 닫고 다시 열 때는 데이터가 사라진다.

 

쿠키

MDN 공식 문서에 따르면 모든 요청에 쿠키가 함께 전송되기 때문에 성능 저하의 원인될 수 있기 때문에 쿠키에 저장하는 방식보단 로컬 스토리지에 저장하는 형식을 조금 더 권장한다.

 

보안적인 측면에서 쿠키 또한 JS로 접근이 가능하기 때문에 서버측에서 HTTP Only,secure,Samesite 등 옵션을 걸어줘여 한다. 위와 같은 방법으로 쿠키 탈취/JS 접근도 제한할 수 있다. 

 

HTTP-only 쿠키는 가장 안전한 방법으로, 브라우저에서 직접 접근할 수 없다. XSS공격에 안전하고 서버와의 통신 시 자동으로 전송된다. 이 때문에 Refresh Token을 저장할 때 주로 사용된다. 

 

쿠키에 저장할 때 보통 httpOnly, secure로 저장한다. 이 두 옵션은 무엇을 의미하는가?

httpOnly가 설정된 쿠키는 JavaScript에서 접근할 수 없다. 즉, 클라이언트 측 스크립트가 쿠키를 읽거나 수정할 수 없게 되어 XSS 공격으로부터 쿠키를 보호할 수 있다.

 

secure은 쿠키가 HTTPS 연결을 통해서만 전송되도록 한다. 이를 통해 중간자 공격(MITM)에서 쿠키가 탈취되는 것을 방지할 수 있다.

 

결론

Access Token은 자주 갱신되므로 클라이언트에서 쉽게 접근할 수 있는 곳에 저장할 수 있지만, 보안상 민감한 정보는 HTTP-only 쿠키에 저장하는 것이 더 안전하다.

Refresh Token은 길게 유지되므로 HTTP-only, secure 쿠키에 저장하여 보안을 강화하는 것이 좋다.

 

 

- 토큰을 관리하는 방법에는 다음 방법이 있습니다. 프로젝트에서는 적절한 방법을 선택하도록 해요.
   - localStorage(또는 Session Storage)
   - 메모리 단에서 관리 1(context API의 전역상태로)
   - 메모리 단에서 관리 2(zustand의 전역상태로)
   - 메모리 단에서 관리 3(tanstack query의 전역상태로)

 

출처:
https://stormstudy.tistory.com/62

https://dreamcode.tistory.com/444