Django

로그인 토큰 저장과 사용자 정보 관리에 대한 생각

traveler_JH 2022. 7. 6. 22:55

토큰의 저장 위치

로그인 성공 시 받아온 토큰을 어디에 저장할까?우선 정해진 답은 없다.

보안의 정도와 서비스 기획 방식에 따라 달라질 것이다.

토큰의 저장위치는 쿠키 vs 로컬스토리지/세션 스토리지 두 경우로 나누어 볼 수 있다.

쿠키에 저장하기

: 백엔드 작업 시 처리해야할 방법이다.

쿠키는 HTTP 통신의 무상태성을 보완해주기 위해 나온 것으로 서버가 클라이언트에 값을 저장하고, 읽을 수 있도록 해줍니다. 이와 관련된 쿠키의 가장 중요한 특성은 서버에서 접근할 수 있으며, 자동으로 요청에 포함된다는 점입니다. HttpOnly 설정을 추가한다면 클라이언트의 접근은 완전히 차단해서 해커가 자바스크립트 코드를 통해 정보를 탈취하는 것을 방지할수도 있습니다.

매우 작은 저장 공간(4KB)을 가지며 쿠키는 모두 일정 기간이 지나면 삭제됩니다. 만료 시점을 기준으로 크게 두 가지로 나뉘며, 브라우저가 종료되면 삭제되는 session cookies와 지정된 만료일에 삭제되는 persistent cookies가 있습니다.

백엔드에서 로그인이 성공되면 access token을 http header에 넣어 로그인에 대한 응답으로 보내고, 브라우저에서는 이 http 응답 헤더에 존재하는 쿠키를 브라우저에 저장하여 사용한다.

그리고 이후의 모든 http 요청에 대해서는 쿠키를 담아 보내게 되고 stateless한 http에서는 동일 사용자의 접속임을 쿠키를 통해 확인할 수 있다.

쿠키를 사용할 때에도 보안과 관련된 이슈가 있다.

CSRF로 해킹이 가능한데,이는 이용자의 쿠키값이 요청에 반영되는 것을 이용해서 특정 사이트로 가장한 유사 사이트에 접속을 유도하고, 쿠키값이 반영되어 있는 상태로 개인정보를 유출하게 끔하는 특정 요청을 보내게 되는 것이다. Same-site정책으로 커버가 가능한데 아직 완전한 상태는 아니다. 그래도 로컬/세션스토리지에 저장하는 것보다는 보안성이 좀더 높다고 할 수 있다.

  • ``쿠키를 사용하기 위해 처리해주어야 하는 내용 :
프론트 : withCredentials : true
서버 : Access-Control-Allow-Credentials : true

스토리지에 저장하기

로그인 성공 후 받은 토큰을 스토리지에 저장한다.

세션 스토리지는 session cookies와 비슷하다고 볼 수 있습니다. 말 그대로 세션을 위한 저장 공간이며 세션이 종료되면 모두 삭제됩니다. 쿠키와 다르게 서버에서 접근할 수 없기 때문에, 다음과 같이 클라이언트에서 스토리지의 값을 꺼내서 서버에 전달해주어야 합니다.

만약 여러 개의 탭을 사용하면 탭 별로 세션 스토리지를 사용합니다. 상당히 큰 저장 공간(5~10MB)을 가집니다.

로컬 스토리지

로컬 스토리지는 persistent cookies와 비슷하다고 볼 수 있습니다. 다만 쿠키는 만료기간이 지나면 삭제되지만 로컬 스토리지의 데이터는 반 영구적으로 저장가능합니다. 세션 스토리지와 마찬가지로 서버에서 접근할 수 없기 때문에, 클라이언트에서 값에 접근해 서버에 전달하는 과정이 필요합니다. 로컬 스토리지도 상당히 큰 저장공간(5MB)을 가집니다.

로컬스토리지는 브라우저 창이 종료되어도 스토리지 값이 유지되고 세션스토리지에서는 브라우저가 종료되면 해당 스토리지도 삭제되는 차이가 있어 서비스의 내용에 따라 (로그인을 유지할 것인지) 정하기 나름이다.또한, 간혹 JWT가 쿠키용량 4KB보다 큰 경우엔 스토리지에 저장해야한다.

스토리지에 저장되는 토큰은 최근에는 주로 JWT로 이뤄지는데스토리지에 저장하는 건 XSS로 인한 위험성이 있지만토큰의 유효기간을 설정하는 등 refresh Token과 같이 여러 방면으로 보안의 약점을 신경쓸 수 있다.

쿠키는 자동적으로 토큰이 요청에 붙지만, JS에 저장된 토큰은아래와 같이 요청 헤더에 작성 해주어야 한다.

Authorization Bearer ${access_token}

(*XSS로 인한 위험_ 해커가 js에 접근해 script 내용을 수정할 수 있는 것,token값을 빼내거나 변경시킬 수 있다.)

  • `` JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON
  • `` 인증받을 시, resource Server로 부터 **access token과 refresh token**을 받는다. access token이 유효기간이 있기 때문에, 기간이 만료되면 refresh token을 통해 새로운 access token을 발급받게 되는 것.

그래서 어디에 저장하는 것이 좋을까?

보안이 크게 중요하지 않다면 로컬 스토리지는 나쁘지 않은 선택이 될 수 있습니다. 쿠키와 다르게 반 영구적으로 많은 저장 공간을 사용할 수 있기 때문에 처음에 한 번 인증만으로 다시는 인증을 하지 않아도 되도록 편하게 구현할 수 있습니다.

하지만 보안의 측면에서 웹 스토리지(로컬 스토리지 + 세션 스토리지)는 좋지 못하다고 할 수 있습니다. 웹 스토리지에 저장된 값은 javascript 코드를 통해 언제든지 접근할 수 있는데, 이는 웹 사이트에 악의적인 스크립트를 넣어 의도하지 않은 동작을 발생시키는 XSS(cross-site scripting)공격에 취약합니다.

반면 쿠키에 저장한 값은 HttpOnly 속성을 통해 javascript를 통한 접근을 막을 수 있습니다. 때문에 보안적인 측면을 생각한다면 웹 스토리지보다는 쿠키에 저장하는 것이 좋다고 할 수 있습니다.