본문 바로가기
항해99/실전 WIL | TIL

[TIL-023] 쿠키 / 세션 / JWT토큰

by junvely 2023. 5. 5.

Today목표 : 05/04일 React Lv4 과제(5) - 쿠키 / 세션 / JWT토큰


클라이언트에서 JWT 토큰 생성하기

문제상황

오늘 과제에서는 토큰을 생성해 클라이언트에서 JSON서버를 이용하여 모든 로그인 과정을 처리하는 과제였다. 토큰 생성은 보통 서버측에서 이루어진다. 각 언어에 따라 라이브러리가 존재하여 어렵지 않게 토큰을 생성할 수 있다.

❗하지만 클라이언트에서 토큰을 생성하는 라이브러리는 사실상 찾기 힘들기 때문에 토큰 생성을 클라이언트에서 하기는 쉽지 않다. 토큰은 보통 서버측에서 발급해 주고 클라이언트에서는 발급된 토큰을 받아 로그인 처리나 사용자 정보를 요청하기 때문이다. 하지만 불가능한 것은 아니었다.

 

시도한점

Node.js에서 사용되는 jsonwebtoken 라이브러리를 사용하면 리액트, 자바스크립트 즉 클라이언트에서도 토큰을 생성할 수 있다. 하지만 오늘 시도해본 결과 몇 가지 문제점들이 있었다. 

1. Node.js 기반이기 때문에, Node버전이 낮거나 높은 등에 따라 따로 설치가 필요한 라이브러리들이 많다. jwt 라이브러리를 이용하기 위해 그 기반이 되는 buffer, stream, until 등 Node환경에서 필요한 라이브러리들을 설치해 주어야 한다.

2. 이 과정에서 Webpack 설정을 만져야 할 일이 생겼다. 문제는 나는 CRA로 현재 진행중이기 때문에 Webpack설정을 세부적으로 다루기 위해서는 eject가 필수적이다. 하지만 한 번 eject할 경우 돌이킬 수 없기 때문에 eject하지 않고 설정을 만질 수 있는 방법이 없나 하다가 찾은 방법은

'react-app-rewired'를 사용하면 CRA의 기본 webpack 설정을 바꿀 수 있다는 것이다. 그리고 resolve.fallback 속성을 사용하여 Node.js 내장 모듈을 브라우저에서 사용할 수 있는 모듈로 변환해줄 수 있다고 한다. 하지만 결과적으로 나는 잘 안됐다... yarn start도 안되고 until 파일도 계속 모듈을 찾을 수 없다고 떴다.. 결국 클라이언트에서 토큰을 생성하기 위해서는 webpack 설정을 만져서 jsonwebtoken Node 라이브러리를 사용해야 할 것 같은데 시간 문제상 거기까지 진행하기가 쉽지 않았고 보통 서버에서 토큰을 주고, 그것을 활용하는 것이 클라이언트에서는 더 중요하기 때문에 mock 서버를 이용해 토큰을 받아서 사용하도록 하려고 한다. 내일부터는 토이프로젝트가 시작되기 때문에 다음 프로젝트에서는 이번에 미흡했던 로그인 과정 처리를 맡아 백엔드로 부터 토큰을 받아서 진행해 보고 싶다.

 

+ npm : jsonwebtoken 관련 문서

 

jsonwebtoken

JSON Web Token implementation (symmetric and asymmetric). Latest version: 9.0.0, last published: 4 months ago. Start using jsonwebtoken in your project by running `npm i jsonwebtoken`. There are 23535 other projects in the npm registry using jsonwebtoken.

www.npmjs.com

+ 위 라이브러리를 활용해 토큰 발급 및 검증 하기

 

자바스크립트로 JWT 토큰을 발급하고 검증하기

Engineering Blog by Dale Seo

www.daleseo.com

 

 

쿠키 / 세션 / JWT / 로컬 스토리지 / 세션 스토리지✅

먼저 오늘 이것들에 대한 전반적인 개념에 대해 이해하면서, 어떤 것을 로그인 시 사용하는게 좋을까에 대해 고민했다.

각각 장단점이 있는 부분이라 무엇이 좋다고 말할 수 없으므로 필요에 따라 선택적으로 사용해야 할 것 같다.

먼저 각각 쿠키 / 세션 / JWT 인증, 인가 방식에 대한 이해를 도울 수 있는 자료를 가져왔다. 헷갈릴 때 마다 보면 좋을 것 같다.

 

1) 쿠키 - 세션을 이용한 인증 방식

- 인증

-인가

 

2) JWT 토큰을 이용한 인증 방식

- 인증

- 인가

 

중요한 점은 각각의 어떤 특징이 있는가? 어떤 인증 / 인가 방법을 선택하여 처리할 것인가? 차이점을 아는 것이다.

❗왜 예제에서는 쿠키 - JWT 토큰을 사용하여 처리했는가?

먼저 JWT토큰을 서버로부터 발급받으면 클라이언트는 로컬 스토리지, 세션스토리지, 쿠키 등에 저장하여 사용할 수 있다.

저번에 로그인 기능을 구현하였을 때는, 서버에서 토큰을 발급받아서 클라이언트에게 넘겨 로컬스토리지 또는 세션 스토리지에 저장하여 사용하였었다. 처음에는 로컬스토리지에 저장하였다가 로그인 처리가 브라우저에 계속 저장되어있으면 안되기 때문에 세션 스토리지로 변경하여 브라우저를 닫거나 하면 휘발될 수 있게끔 만들었다. 이와같이 로컬 스토리지는 로그인 시나 사용자 정보를 저장하는 용도로는 사용되지 않는다고 한다. 세션 스토리지나 쿠키에 많이 저장된다.

여기서 든 또 하나의 의문은, 세션 스토리지도 있는데 왜 쿠키에 저장했을까? 였다. 쿠키에 대해 공부하고 나니 깨달은 점은 쿠키는 클라이언트에서 따로 토큰을 전달받아 스토리지에 set하는 과정을 거칠 필요없이 서버에서 JWT를 발급하여 쿠키에 set하면 는 클라이언트의 쿠키 스토리지에서 바로 사용할 수 있다. 따라서 세션 스토리지 보다 더 간편하다는 장점이 있었다. 그 외의 자세한 장단점은 더 공부가 필요할 것 같다.

 

❗서버의 세션이냐, JWT 토큰이냐 ?

여기서 서버의 세션과 로컬의 세션 스토리지는 다르다. 서버의 세션은 사용자와 서버 간의 연결이 활성화된 상태를 의미하는 개념이다(또는 인증이 유지되고 있는 상태). 로그인 성공 시 서버에서 세션을 생성하고 key-value 형식으로 저장한 다음, sessionId = key를 브라우저의 쿠키로 응답한다. 해당 sessionId에 따른 사용자 정보는 세션에 저장된다. 토큰과 같이 id값을 발급한다는 점에서 JWT와 비슷한 역할을 한다고 볼 수 있지만 세션은 서버에서 사용자 정보를 관리하기 때문에 보안적인 측면에서 더 안전하다고 할 수 있다. 

JWT같은 경우는 토큰에 사용자 정보를 담아 클라리언트에게 전달하고, 클라이언트에서 사용자 정보를 가지고 있는다. 클라이언트가 토큰을 가지고 있는다는 것은 어떻게 보면 보안적인 부분에서 상당히 위험할 수 있다. 사용자 정보가 유출될 가능성이 높기 때문이다. 이런 문제 때문에 예전 프로젝트에서 카카오 로그인 서비스를 담당했을 때 토큰을 클라이언트에서 가지고 있어야 하냐, 서버에서 가지고 있어야 하냐를 프론트측에서 고민하였고, 유출 위험이 있다고 판단되어 백엔드쪽에서 토큰을 관리하도록 요청드렸다.

Access Token 리소스 접근 인가를 받기 위해 사용되는 토큰이다. Access Token의 만료기간을 길게 잡고 인증상태를 오래 가져갈 경우 서버 부담은 줄어드나 보안성(탈취 당할 경우)에 허점이 있다. 따라서 보안이 중요한 서비스에서는 Access Token의 기간을 30분 정도로 짧게 가져가고, Refresh Token은 1~2주 정도로 길게 잡는 경우가 많다고 한다.

이렇게 해서 Access Token이 만료되었을 때 Refresh Token이 유효한 상태면 새로운 Access Token을 클라이언트에게 발급해 인증상태를 유지할 수 있도록 하고 Refresh Token 만료시 다시 로그인하라는 형식으로 응답한다.

서버의 세션에서 사용자 정보를 관리하느냐, JWT 토큰을 사용하느냐에 대해서는 하루만에 답을 내리지는 못할 것 같다. 저번에는 JWT를 사용해 세션스토리지에서 관리하였었다. JWT는 보안성은 약하고 그 보완점으로 refresh 토큰을 통해 보안을 강화 하였다. 또 상대적으로 세션에 비해 비용이 적다는 장점이 있었다.

세션은 리소스가 많이든다. 비용이 많이 든다고 들었지만 아직 정확하게 어떤 부분에서 그런 것인지는 아직 모르겠다. 쿠키나 스토리지들도 메모리를 차지한다고 알고 있는데 각각의 장단점을 더 딥하게 공부해 보고 적절한 상황에 맞게 사용해야 할 것 같다.  

결론적으로는 1. 로그인 인증/인가 방식으로는 1. 쿠키 - 세션 또는 2.쿠키 - JWT 조합으로 많이 사용되는 것 같고, 부분적으로 자동 로그인 기능 등 스토리지의 휘발성과 장단점에 따라 어디서 관리해야 할지도 고민해 보아야 한다. 

또 2. 보안적인 측면, 비용적인 측면도 고려하여 세션에서 관리할지, JWT로 관리할지도 생각해 보아야 할 문제인 것 같다. 아직은 공부한 지 하루밖에 안됐기 때문에 프로젝트를 진행하면서 계속 고민해 보아야 할 것 같다.

3. 클라이언트에서는 사실 토큰 발급 후, 로그인 처리 라던지 인가의 과정이 더 중요하기 때문에 그 부분의 처리과정 또한 계속 연습해 보아야 할 것이다.

 

 

+ token decode 해독 라이브러리

 

jwt-decode

Decode JWT tokens, mostly useful for browser applications.. Latest version: 3.1.2, last published: 2 years ago. Start using jwt-decode in your project by running `npm i jwt-decode`. There are 3969 other projects in the npm registry using jwt-decode.

www.npmjs.com