로그인 인증 방식, 웹 로그인 유지에 대해

배준형·2022년 3월 29일
0

1. Authentication | Authorization

  1. Authentication(인증): 로그인

특정 서비스의 특정 권한이 주어진 사용자임을 확인하는 것. ID | Password를 통해 서비스의 권한이 주어진 사용자인지 확인하는 로그인 과정에 Authentication이 필요하다.


  1. Authorization(인가): 권한

한 번 인증을 받은 사용자가 이후 서비스의 여러 기능을 사용할 때 무엇을 할 수 있는지 결정하는 규칙이다. 블로그에 로그인한 사용자가 글을 올린다던지, 본인 아이디로 댓글을 작성하는 등의 행위에 Authrization이 필요하다.


2. 로그인 상태를 유지하는 방법

사용자의 로그인 상태를 서버에서 처리하는 데 사용할 수 있는 방법은 세션을 기반으로 인증하는 것, 토큰을 기반으로 인증하는 것이 있다.


2-1) 세션 기반 인증

서버가 사용자가 로그인 중임을 기억하는 방법이다. 사용자가 로그인하면 서버는 세션 저장소에 사용자의 정보를 조회하여 Session ID를 발급하고, 발급된 id는 브라우저의 쿠키에 저장한다.

이를 이용해 사용자가 요청을 보낼때마다 서버는 세션 저장소에서 세션을 조회하여 로그인 여부를 확인한 후 응답을 하여 로그인 상태를 유지할 수 있다. 서버에서 세션 ID는 메모리, 디스크, 데이터베이스에 저장된다.

만약 에러가 발생하게되어 서버를 재부팅해야할 때 세션 정보는 사라지게 되기에 로그인을 다시 해야 하고, 어플리케이션의 규모가 커서 서버를 여러대 사용한다면 모든 서버끼리 같은 세션을 공유해야 하므로 신경써야 하는 부분이 많아질 수 있다.

※ 쿠키?

쿠키란 사용자의 로그인, 장바구니, 테마 등의 정보를 저장하는 데이터 조각으로 4kB의 용량 제한을 갖고 있고, HTTP 요청 시마다 쿠키가 요청 Header에 담겨 데이터를 전송한다.


2-2) 토큰 기반 인증

토큰은 로그인 이후 서버가 만들어 주는 문자열이다. 이 토큰 내부에는 사용자 로그인 정보, 서버에서 발급되었음을 증명하는 서명이 들어있어 이를 이용해 로그인을 유지하는 방법이다.

토큰에는 서버에서 발급되었음을 증명하는 서명이 들어있기 때문에 무결성(정보가 변경, 위조되지 않는 성질)이 보장된다. 이를 이용해 사용자가 요청을 보낼 때마다 토큰과 함께 요청을 보내게 되고, 서버에서는 요청에서 받은 토큰이 유효한지 검사하고, 이에 따라 응답한다.

서버에서 사용자 로그인 정보를 기억하기 위해 사용하는 리소스가 적고, 서버가 여러개 늘어나더라도 요청을 보내는 쪽(클라이언트)에서 토큰을 소유하고 있으므로 로그인 상태를 공유하고 있을 필요가 없다는 장점이 있다.


3. JWT(JSON Web Token)란?

JWT는 데이터가 JSON으로 이루어져있는 토큰을 말하고, 로그인 유지 방법 중 토큰 기반 인증을 위해 사용된다.

3-1) JWT의 구조 (?)

JWT의 구조는 점(.)으로 구분된 세 부분으로 구성되며 다음과 같은 형태를 갖는다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c


  1. Header

첫 번째 점(.) 이전의 내용은 Header이다. Header는 토큰의 Type, 알고리즘으로 나뉜다. Type(typ)은 언제나 "JWT"라는 값이어야 하고, 알고리즘(alg)은 3번 Signature 값을 만드는데 사용될 알고리즘(HS256 등)이 지정된다.

{
  "alg": "HS256",
  "typ": "JWT"
}
  • Header 부분 Base64Url 디코딩 시 나타나는 JSON

  1. Payload

두 개의 점(.) 사이의 내용은 Payload이다. Payload를 Base64Url을 이용해 디코딩하면 사용자에 대한 정보(Clain)가 JSON 형태로 나타나게 된다.

Payload에는 누가 누구에게 JWT를 발급했는지, 토큰이 언제까지 유효한지, 서비스가 사용자에게 토큰을 통해 공개하기 원하는 내용은 무엇인지에 대한 내용이 담겨있다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • Payload 부분 Base64Url 디코딩 시 나타나는 JSON

  1. Signature

두 번째 점(.) 이후의 내용은 Signature이다. Header와 Payload값, 서버에 저장된 secret 값을 사용하여 Header에서 alg로 정한 알고리즘을 적용하면 나타나는 서명 값이다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

※ stateless | stateful

  • stateless: 시간에 따라 바뀌는 어떤 상태 값을 갖지 않는 것. 토큰 기반 인증 방식
  • stateful: 시간에 따라 바뀌는 어떤 상태 값을 갖는 것. 세션 기반 인증 방식

4. JWT 방식의 문제점

여기까지 살펴보면 토큰 기반 인증 방식이 세션 인증 방식보다 좋은 방법처럼 보인다. 어떤 방식이 더 좋다고 할 수는 없지만, 토큰 방식 인증에도 문제점이 있다.

만약 악의적인 사용자가 토큰을 탈취해버리면 이를 무효화할 방법이 없다.
그리고, 단 하나의 로그인만 유지될 수 있는 서비스를 구현하려면(인터넷 강의를 위한 로그인 등) 세션 인증 방식이라면 기존의 세션을 제거하고 새로운 세션 ID만 유지하면 되지만, 토큰 인증 방식으로는 이를 제어하기가 어렵다.


5. 정리

세션 인증 방식이 서버를 확장하기가 번거롭고 신경써야 하는 부분도 많지만 이를 잘 작성하기만 한다면 기억하는 세션에 대한 상태들을 언제든 제어할 수 있기 때문에 사용 목적에 따라 적절히 선택하여 사용하면 될 것이다.

4번에서 살펴본 JWT 방식의 문제점으로 인해 JWT만으로 구현된 로그인 인증 방식은 결함이 존재한다. 따라서 이를 적용하기에 서비스가 적합한지 충분히 고려하여 선택하면 될 것이다.


참고

https://www.youtube.com/watch?v=1QiOXWEbqYQ&t=309s

https://jwt.io/

profile
프론트엔드 개발자 배준형입니다.

0개의 댓글