세션(Session)과 JWT

GOTAEUK·2022년 2월 21일
9
post-thumbnail

🔎 Authentication vs Authorization

두 개의 단어는 비슷해보이지만 엄연히 다른 프로세스이다. Authentication은 인증이고, Authorization은 권한 부여인데 로그인 시스템에서 중요한 역할을 한다. 웹사이트에서 로그인하는 것을 Authentication이라고 한다. 한번 로그인을 한 후에는 로그인 상태가 유지되어야 한다. 이 역할을 하는 것이 Authorization이다. 권한 부여를 통해 로그인 상태의 사용자만 사용할 수 있는 기능을 사용할 수 있게 한다. 어떤 요청마다 로그인을 할 수 없는 노릇이니 로그인 상태를 유지시키는 기술이 필요하다. 이때 사용될 수 있는 기술이 세션이나 JWT이다.


🔎 세션(Session)

세션은 브라우저와 웹 서버가 연결되어 브라우저가 종료될 때까지의 시점이다. 브라우저를 통해 서버에 접속할 때 서버는 세션 id를 쿠키에 담아 되돌려주고, 사용자는 세션 id를 담은 쿠키인 세션 쿠키를 이 후 요청부터 계속해서 함께 전달함으로 서버가 클라이언트를 식별할 수 있게 하는 기술이 세션 기반 인증 방식인데 보통 세션이라고 한다.

클라이언트가 HTTP요청을 보낼 때 쿠키에 세션 id가 없다면 서버는 세션 id를 생성 해 쿠키에 담아서 돌려준다. 다시 HTTP 재요청을 할 때 쿠키를 보내기 때문에 서버에서는 세션 id를 통해 클라이언트를 식별할 수 있는 것이다.

📌 쿠키 vs 세션

세션은 HTTP의 stateless 속성을 보완한다는 점에서 쿠키와 자주 비교되곤 한다. 쿠키의 유형에는 영구 쿠키와 세션 쿠키가 있어 만료시기가 각각 다르지만 세션은 대부분의 경우 브라우저 종료 시 만료된다. 쿠키와 세션의 가장 큰 차이는 저장 위치이다. 쿠키는 클라이언트에 저장되고, 세션은 서버에 저장된다. 그러나 서로 반대 되는 개념이 아니라 세션 id를 쿠키에 담아서 통신한다는 점에서 세션은 쿠키를 사용하는 방식이라고 볼 수 있다. 쿠키에 로그인에 대한 정보를 담는다면 클라이언트에 노출 되어 위험하기 때문에 서버에 저장하는 방식으로 세션을 사용한다.

📌 세션의 단점

세션기반 인증 방식을 사용할 때 중앙 세션 관리 시스템에서 하나의 문제가 시스템 전체로 확산된다는 문제점이 있다. 또 다른 문제점은 사용자가 많아짐에 따라 세션 DB와 서버를 확장해야 한다는 점이다. 예를 들어 내가 사용하고 있는 어떤 웹사이트에 사용자가 많아져 세션DB를 A와 B로 나누었다고 가정해보자. 나에 대한 정보는 세션 A에 저장되어 있었다. 그렇다면 앞으로 해당 웹페이지에 request를 보낼 때 세션 A에서만 통신하도록 하는 추가적인 기술이 필요할 것이다.


🔎 JWT

위의 단점을 어느 정도 해결할 수 있는 기술이 JWT이다. JWT는 JSON Web Token의 약자로 이상한 형태의 문자열이다.

📌 구성

.을 기준으로 구분되어 heaer, payload, signature로 구성 되어 있다. JWT는 암호화되지 않아서 누구나 확인할 수 있기 때문에 중요한 정보를 JWT에 담으면 안된다.

  • header: typ와 alg라는 정보가 존재하는데 typ의 값은 JWT이고 alg signature를 해싱하기위한 알고리즘이다.
{
	"alg": "HS256", 
	"typ": JWT 
}
  • payload: 토큰에서 사용할 조각들인 클레임이 존재한다. 토큰의 목적에 따라 클레임이 달라진다. registered claim에는 토큰 만료시간, 토큰 발급 날짜 등을 작성할 수 있다.
  • signature: 토큰을 인코딩하거나 유효성 검사를 할 때 필요한 암호화 코드이다.

📌 동작방식

쉽게 설명하자면 JWT는 일종의 확인서이다. 우리가 어떤 웹사이트에 로그인을 해서 성공적으로 Authentication이 이루어지면 서버는 사인된 확인서(JWT)를 우리에게 제공한다. 그러면 앞으로 요청 때마다 JWT를 서버에게 같이 보여주면서 권한을 확인받는 것이다. 서버는 JWT만 확인해 Authorization하기 때문에 세션 DB에 저장할 필요가 없다.

📌 JWT 저장위치

JWT를 웹에서 저장하기 위해서는 브라우저 저장소에 저장하는 방식과 쿠키에 저장하는 방식을 사용할 수 있다. 로컬 스토리지와 세션 스토리지 같은 브라우저 저장소에 JWT를 저장한다면 스크립트 공격(XSS)에 취약해진다. 쿠키에 저장할 때 http-only 를 사용한다면 HTTPS로만 쿠키가 전달되기 때문에 보안을 강화할 수 있고, CSRF 문제에 대해서는 CSURF같은 라이브러리를 사용함으로 해결할 수 있다.


🔎 세션 vs JWT

세션방식에서 서버는 로그인 된 유저의 정보를 모두 저장하고 있어서 유저들의 통제가 JWT보다 비교적 쉽다. 만약 PC와 모바일기기에서 동시 접근하는 것을 막고 싶을 때 강제 로그아웃 시키는 기능은 세션을 통해 구현이 가능하다.

JWT를 서버가 발급하고나면 JWT를 관리하지 않는다. 오직 JWT를 받았을 때 JWT가 유효한 것인지만 확인하기 때문에 서버 자원과 비용을 절감할 수 있다. 그러나 JWT가 수명이 길어서 제 3자에게 탈취당할 경우가 발생할 수 있다. 이를 보완한 방법 중 하나로 access token & refresh token 방식이 있는데 두개의 토큰 모두 JWT이다.

📌 access token & refresh token

access token & refresh token 방식은 토큰들에 유효기간을 주어서 보안을 강화시킨 것이다. access token은 유효기간이 짧은 토큰이고, refresh token은 access token보다 유효기간이 긴 토큰이다.

  1. 사용자가 로그인을 하면 서버로부터 access token, refresh token 2개의 토큰을 받는다. 이때 서버는 refresh token을 안전한 저장소에 저장한다.

  2. 서버로부터 받은 access token의 유효 기간이 지나지 않은 경우 사용자가 어떤 요청을 보낼 때 access token을 함께 보내고 서버는 유효한 지 확인 후 응답을 보낸다.

  3. 서버로부터 받은 access token의 유효 기간이 지난 경우 사용자는 refresh token과 함께 요청을 보내고, 저장소에 저장되어 있던 refresh token과 비교한 후에 유효하다면 새로운 access token과 응답을 함께 보낸다.


출처 및 참고

profile
한걸음씩

0개의 댓글