로그인 방식에 대해 알아보자

LSM ·2022년 2월 7일
5

작성 배경

이 글에서는 두가지 로그인 방식에 대해 비교하며 정리하는 방식으로 글을 작성하겠다. 먼저 필자는 최근 모바일 앱 개발에 벡엔드를 맡게 되었다. 학교 친구들끼리 하는 사이드 프로젝트이다..ㅎ 일단 부끄럽지만 본인은 근 1년간 짧고도 얕은 웹 개발 공부를 하면서 세션 로그인 방식으로만 로그인을 진행해 보았다.. 그러다 이번에 JWT 토큰 인증방식으로 로그인을 구현해 보아 세션과 토큰인증 방식의 차이를 정리하고 싶어 글을 작성한다.

0. 왜 인증/인가를 거쳐야 하는가?

HTTP는 기본적으로 stateless상태이다. 즉, 서버로 가는 모든 요청이 이전 리퀘스트와 독립적으로 다뤄진다. 그래서 요청이 끝나면 서버는 유저가 누군지 잊어버리게 된다. 따라서 요청할 때마다 우리가 누군지 알려줘야 한다.

인증:

유저가 누구인지 확인하는 절차, 회원가입하고 로그인 하는 것.

인가:

유저에 대한 권한을 허락하는 것.

1. 세션과 쿠키를 이용한 로그인

기존 로그인은 사용자 인증 정보를 매번 request에 담아 요청하였다. 계정정보를 매번 요청(request)에 넣어 보내기엔 보안이 매우 취약하다. 따라서 나온 인증방식이 Session / Cookie를 이용한 로그인 방식이다.

해당 인증 과정의 flow를 보자면 아래와 같다.

브라우저에 존재하는 쿠키에 세션 id를 발급하여 매 요청마다 브라우저의 쿠키를 검증하여 세션 아이디를 통해 사용자를 인증한다.

쿠키는 그저 세션ID를 전달하기 위한 매개체일 뿐이다.

세션을 이용해 iOS, Android앱을 만들 수 있지만 쿠키는 사용할 수 없다. (쿠키는 브라우저에만 있고 네이티브 앱에는 없음.) 이 경우에 '토큰'을 사용해 서버에 '토큰'을 보낸다. 이러한 이유로 모바일 앱의 인증을 위해 jwt 토큰을 공부하게 되었다..

Tip) 세션과 쿠키 개념 :
세션은 서버에서 가지고 있는 정보이며 쿠키는 사용자에게 발급된 세션을 열기 위한 열쇠를 의미. 쿠키만으로 인증을 사용한다는 말은 서버의 자원은 사용하지 않는다는 것이며, 이는 즉 클라이언트가 인증 정보를 책임지게 된다. 그렇게 되면 위의 첫번째 방식처럼 HTTP 요청을 탈취당할 경우 보안상 큰일이다.

세션 방식의 문제점은?

앞서 언급했던 것 처럼 클라이언트가 인증 정보를 책임지게 된다면 보안성 문제도 있다. 하지만 추가적인 문제도 역시 존재하는데 가장 큰 단점 중 하나는 SSO 서비스시 세션 유지의 문제이다.

Single Sign On(통합인증) :

말 그대로 하나의 서버에 대한 인증으로 여러 서버에 인증을 거쳐주는 서비스를 의미한다. 예를 들면, 회사의 홈페이지에 로그인시 다른 영업부 서버나 마케팅부의 서버에 개별적으로 로그인을 할 필요가 없다. 그렇다면 어떻게 하는가? 일반적으로 서버가 하나라면 WAS의 세션 저장소를 이용할 수 있지만 이는 WAS 재실행되면 세션 정보가 날라간다. 추가적으로 WAS를 통한 세션 저장시 여러대에 서버에 세션을 유지하기 위해서는 WAS 세션 동기화과정이 필요하거나 DB의 사용이 필요하다. 그래서 이러한 문제로 자주 사용되는 DB 가 인메모리 DB인 Redis이다.
Redis는 유료이다 하하..
이러한 문제를 해결 할 수 있는 것이 JWT 토큰이다!


2. JWT 토큰 인증

JWT는 Json Web Token의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다. 위의 세션/쿠키 방식과 유사하게 사용자는 Access Token(JWT 토큰)을 HTTP 헤더에 실어 서버로 보내게 된다.

그럼 JWT는 어떻게 생겼는 지를 보겠다.


위에서 보듯 JWT 토큰은 3 영역으로 나누어진 값들이 해쉬로 암호화된 문자열이다.
ex) asdasdadasd.asdasdasdasdasd.sdasdadasdas

일반적으로 헤더에는 해쉬를 위해 사용된 함수 정보, payload에는 암호화 하고자하는 정보가 저장되어있으며, Sgnature는 헤더에 정의된 알고리즘을 통해 암호화한 비밀 값으로 서버만 알고 있다. 이러한 토큰 정보를 통해 사용자는 인증 혹은 인가를 거치게 된다.

위에서 말했듯이 Header, Payload는 인코딩될 뿐(16진수로 변경), 따로 암호화되지 않는다. 따라서 JWT 토큰에서 Header, Payload는 누구나 디코딩하여 확인할 수 있다. 여기서 누구나 디코딩할 수 있다는 말은 Payload에는 유저의 중요한 정보가 들어가면 쉽게 노출될 수 있다는 말이 된다.

하지만 Signature는 토큰 해쉬를 위한 SECRET KEY를 알지 못하면 복호화할 수 없다. A 사용자가 토큰을 조작하여 B 사용자의 데이터를 훔쳐보고 싶다고 가정해보자. 그래서 payload에 있던 A의 ID를 B의 ID로 바꿔서 다시 인코딩한 후 토큰을 서버로 보냈다. 그러면 서버는 처음에 암호화된 Signature를 검사하게 된다. 여기서 Payload는 B사용자의 정보가 들어가 있으나 Verify Signature는 A의 Payload를 기반으로 암호화되었기 때문에 유효하지 않는 토큰으로 간주하게 된다. 여기서 A사용자는 SECRET KEY를 알지 못하는 이상 토큰을 조작할 수 없다는 걸 확인할 수 있다.

이제는 JWT Token의 인증/인가 flow를 살펴보자

사용자는 로그인 이 확인되면 JWT 토큰인 AccessToken 과 RefreshToken을 발급받는다. 여기서 AccessToken 과 RefreshToken 앵??? 왜 두개가 발급 되지... 라고 생각 할 수 있다

이는 보안과 매우 밀접한 관련이 있는 요소이다.

세션은 서버 쪽에서 관리가 가능하기에 세션을 이용한 경우 세션값은 사용못하게 하는 등 제어할 수 있다. 반면 JWT는 이미 줘버린 토큰을 뺏을 수가 없다..
따라서 로그인시 accessToken, refreshToken 두 개의 토큰의 역할을 다르게 준다. accessToken은 실제 인증/인가를 위해 쓰이며 accessToken의 수명은 짧게 한다. 그러다 accessToken의 수명이 다했을 때 accessToken을 재발행 받기 위한 토큰인 refreshToken을 두는 것이다.
즉 refreshToken은 서명과 관련 없이 accessToken을 재발행만을 위해 존재한다. 일반적으로 refreshToken은 만료기간이 길다. 물론 은행과 같이 사용자의 편의성 보다 보안의 목적을 치중하고 싶은 경우, refreshToken은 만료기간이 짧아 질 수 밖에 없다. (누군가를 로그아웃시키려면 refeshToken을 db에서 지워버리면 되는데 그래도 accessToken의 수명 동안은 바로 차단할 방법은 없다고 한다...)

이렇게 발급받은 토큰들을 최신화 시키고 이를 검증하며 사용자의 인증/인가 과정이 일어나는 것이 토큰기반 로그인 방식이다.

JWT 토큰의 특징

장점 :

  1. 세션/쿠키는 별도의 저장소의 관리가 필요하나 JWT는 발급한 후 검증만 하면 되기 때문에 추가 저장소가 필요없다. 이는 Stateless 한 서버를 만드는 입장에서는 큰 강점이다. 여기서 Stateless는 어떠한 별도의 저장소도 사용하지 않는, 즉 상태를 저장하지 않는 것을 의미한다. 이는 서버를 확장하거나 유지,보수하는데 유리하다.
  1. 세션 로그인 시 발생할 수 있는 SSO 서비스를 쉽게 구축할 수 있다. 즉 확장성이 뛰어나다.

단점 :

  1. 앞서 언급한 바와 같이 이미 발급된 JWT에 대해서는 돌이킬 수 없다.
  1. Payload 정보가 제한적이다. 위에서 언급했다시피 Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있다. 세션/쿠키 방식에서는 유저의 정보가 전부 서버의 저장소에 안전하게 보관됨. 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없다.
  1. JWT의 길이다. 세션/쿠키 방식에 비해 JWT의 길이는 길다. 따라서 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 된다.

최종 정리

각 로그인 방식마다 장 단점이 있는 듯 하다.

우리가 잘 알고 있는 넷플릭스는 한 아이디마다 공유할 수 있는 디바이스 수가 제한적이다. 이는 서버가 현재 로그인한 디바이스나 사용자의 정보를 가지고 있기 때문에 가능한 일이다. 추가적으로 세션방식은 로그인 되어있는 계정의 연결을 끊는 등을 가능하게 해 준다.

이처럼 필요한 역할과 환경에 맞게 유연한 인증/인가 방식을 사용할 수 있고 설계할 수 있는 것이 가장 기본적이면서 가장 중요한 일임을 알 수 있었다...!!!


참고자료

https://velog.io/@sksgur3217/JavaScript

https://velog.io/@aaronddy/인증Authentication과-인가Authorization

https://velog.io/@lgs2722/쿠키Cookies-세션Sessions-토큰Token-JWT의-기본개념

profile
개발 및 취준 일지

0개의 댓글