로그인 톺아보기 - 세션, 토큰, 쿠키, JWT

PinkTopaz·2022년 12월 29일

로그인 톺아보기

목록 보기
1/1

💡 인가? 인증?

인증(Authentication)

사용자가 어떤 사이트에서 권한이 있는 회원임을 아이디와 패스워드로 확인받는 것으로, 로그인과 동일하다.

인가(Authorization)

한 번 인증을 받은 사용자가 이후 서비스의 여러 기능을 이용할 때,
내 계정으로’만’ 할 수 있는 활동을 시도할 때 (ex. 댓글 달기, 글 쓰기) 내가 로그인 되어있음을 알아보고 허가를 해주는 것!



💡 웹 서비스는 사용자가 로그인된 사용자인지 어떻게 알아볼 수 있을까?

1. (전통적) 세션 방식

세션: 서버에 로그인 되어있음이 지속되는 상태

사용자가 로그인에 성공하면, 서버는 ‘세션 표딱지(세션 정보)’라는 것을 출력한다.

이걸 반으로 갈라서
반쪽은 브라우저(ex. 크롬, 엣지)에,
반쪽은 책상(메모리, 가장 빠르다), 서랍(하드), 창고(데이터베이스) 등에 올려놓는다.

브라우저: 받은 표딱지 반 쪽을 세션 ID로 저장하고, 해당 사이트에 요청을 보낼 때마다 쿠키에 세션 ID를 같이 실어보낸다.

서버: Session ID를 확인해서, 메모리에 해당 Session ID와 맞는 짝이 있는지를 찾아서 짝이 있으면 인가를 해준다.

→ 중요한 유저 정보는 모두 서버에 있고, 여기서 쿠키는 그저 세션 ID를 운반하는 매개체로 역할한다.

2. 토큰 방식의 JWT(JSON Web Token)

사용자가 로그인을 하면 토큰이라는 표를 출력해준다.

하지만, 이번에는 반반 쪼개서 서버와 나눠갖는 것이 아니라 브라우저에만 이 토큰, JWT를 준다.
즉, 서버가 뭔가를 기억하지 않고 있다.

브라우저: JWT를 쿠키, 로컬스토리지 등에 저장해두었다가 사이트에 요청을 보낼 때 JWT를 함께 보낸다.

서버: 서버는 해당 JWT의 유효성을 검사하고 인가한다.



💡 세션 방식 VS JWT

📌 세션 방식

장점 : 서버는 로그인 된 유저의 모든 정보를 저장하기 때문에, 해당 정보를 이용하면 새로운 기능들을 추가할 수 있게 된다.
→ 특정 유저를 쫓아내고 싶을 때, 그냥 세션 DB에서 해당 유저의 정보를 삭제시키면 된다.

단점 : 사용자가 동시에 많이 접속하는 경우 메모리 부족 문제가 생길 수 있고, 서버에 문제가 있어서 꺼져버리면 메모리에 있던 모든 정보가 날아간다.

📌 JWT

JWT의 장점

  1. 서버의 메모리에 저장 공간을 확보할 필요가 없다. 토큰을 브라우저에 주고, 브라우저가 페이지를 요청하면 서버는 해당 토큰이 유효한지만 검증하면 된다.

  2. 세션ID를 운반하는 쿠키를 사용할 수 없는 모바일 어플리케이션에는 JWT를 사용한 인증방식이 최적이다.

JWT의 단점

  1. 악의적인 사용자는 토큰의 유효기간이 지나기 전까지 정보 탈취가 가능하다.
    → 토큰이 만료되기 전까지는 계속 유효하니까 강제 로그아웃과 같은 기능은 구현할 수가 없다. 누군가 이 토큰을 뺏어가도 다시 가져올 방법이 없다.

  2. JWT의 길이가 길기 때문에 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 된다.

📌 JWT의 한계를 보완하는 방법

토큰의 수명을 아주 짧게 주고, 해당 토큰의 수명을 계속 연장한다.

유저가 로그인을 하면, 서버는 2개의 토큰 을 발급한다.
그 2개의 토큰이 바로 accessToken, refreshToken 이다.

  1. accessToken의 수명이 다하면 서버에 refreshToken을 보낸다.
  2. refreshToken은 상응값을 데이터베이스에도 저장한다.
  3. 서버는 데이터에 저장된 값과 accessToken을 비교해보고 맞다면 새 accessToken을 발급해준다.
    → refreshToken만 안전하게 관리된다면, 이게 유효할 동안은 다시 로그인을 할 필요가 없어지는 것이다.


💡 쿠키, 세션, 토큰 조금 더 톺아보기!

🍪 쿠키

쿠키를 이용해서 서버는 브라우저에 데이터를 넣을 수 있다.

사이트에 방문하면

브라우저 → 서버 : 요청을 보내고

서버 → 브라우저 : 응답을 한다.

이 응답에는 모든 데이터와 내가 찾던 페이지 정보가 있고,

그 응답에는 브라우저에 저장하고자 하는 쿠키가 있을 수 있다.

브라우저에 쿠키를 저장하고, 해당 웹 사이트에 방문할 때마다 브라우저는 해당 쿠키도 요청과 함께 서버에 보내게 된다.

📍 쿠키의 특징

  • 쿠키는 도메인에 따라 제한이 된다. → 유튜브가 준 쿠키는 유튜브에만 보내지고, 크롬이 준 쿠키는 크롬에만 보내진다.

  • 쿠키는 유효기간이 있고, 그 기간은 서버가 정한다.

  • 쿠키는 인증 뿐만 아니라 다양한 정보를 담을 수 있다.
    ex) 웹사이트에서 언어 설정을 바꾸면, 서버는 쿠키를 준다.
    다음에 내가 그 웹사이트에 방문하면 쿠키는 요청과 함께 서버로 보내지고, 서버는 쿠키가 기억해둔 언어설정의 페이지를 제공한다!

✨ Stateful VS Stateless

웹사이트를 이용할 때 쓰는 프로토콜인 HTTP는 stateless하다.
즉 서버로 가는 요청이 이전 요청과는 독립적으로, 이전 요청이 어쨌든지 상관하지 않고 현재 요청을 처리한다!
따라서 서버에 요청할 때마다 요청을 보내는 주체가 누군지 알려줘야 한다.

→ 이걸 하는 방법 중 stateful한 방법이 세션(state가 세션 DB에 저장된다), stateless한 방법이 토큰 방식

🪙 토큰

쿠키는 공간제약이 있어 길이가 짧은데, 토큰은 그렇지 않아서 굉장히 길다!

헤더(Header)

토큰의 타입과 alg를 포함한다.

토큰의 타입: 언제나 JWT로 고정된다.
alg : 서명값을 만드는데 사용될 알고리즘으로, 여러 암호화 방식 중 하나를 지정할 수 있다.

페이로드(Payload)

클레임(Claim) 이라고 불리는 데이터를 담고 있다.
클레임은 이 토큰을 누가 누구에게 발급했는지, 이 토큰이 언제까지 유효한지, 서비스가 사용자에게 토큰을 통해 공개하고 싶은 내용 (ex. 사용자 닉네임, 서비스 레벨, 관리자 여부) 등의 정보를 포함한다.

→ 이러한 정보들이 Payload에 실려서 브라우저에서 서버로 요청이 들어오기 때문에, 서버는 DB를 뒤져보지 않아도 사용자에 대한 정보를 알 수 있다.

서명(signature)

헤더 + 페이로드 정보 + 서버만이 알고 있는 secret key(아무나 정보를 조작할 수 없게 함)를 헤더에 포함된 alg에 넣고 돌리면 나오는 결과값

서버는 토큰이 들어오면 해당 토큰의 헤더, 페이로드 값을 "서버의 비밀키"와 함께 돌려봐서 계산된 결과값이 서명값과 같은지를 확인한다.

같다 + 토큰의 유효기간이 지나지 않았다 → 인가
같지 않다 → 정보를 조작한 사용자나 해커로 간주되어 거부


참고자료
세션 vs 토큰 vs 쿠키? 기초개념 잡아드림. 10분 순삭!
세션 VS. 토큰! JWT가 뭔가요?
[JWT] JSON Web Token 소개 및 구조
세션 vs 토큰과 JWT

profile
🌱Connecting the dots🌱

0개의 댓글