인증(Authentication)과 인가(Authorization)
백엔드 개발자를 꿈꾸는 사람으로서 주로 스프링부트를 이용하여 개발을 한다.
그저 기능개발을 위해서라면 단순 구글링을 통해 어찌저찌 완성시킬 수 있지만 만든 후에 내 머릿속에 크게 남는게 없는 느낌이 든다.
글을 정리하며 머리속에 남겨보도록 하자.
사용자 인증(Authentication)과 권한 부여(Authorization)
Authentication이라 불리는 인증은 말그대로 '인증'을 뜻한다. 예를 들어 클라이언트가 서비스를 이용하기 위해 '로그인'을 하는 과정이 해당된다.
Authorization이라 불리는 인가(권한 부여)는 '인증' 단계를 거친 사용자에게 특정 리소스나 기능에 접근할 수 있는 권한을 부여하는 것이다. 예를 들어보면 사이트에 접속한 클라이언트가 특정 파일 또는 글에 접근하려 할 때 접근 할 수 있는 권한이 있는지 확인하는 과정이다.
이러한 인증과 인가를 이용하면 어떠한 사용자가 언제 어떻게 정보를 사용하였는지 파악할 수 있으므로 대부분의 사이트에서 이 과정을 거친다.
인증 (Authentication)
인증에도 여러가지 방식이 있는데 이 글에서는 세션 기반 인증, 토큰 기반 인증, Oauth 외부 인증 에 대해서 알아보겠다.
세션(Session) 기반 인증
세션을 얘기할 때 항상 비교해서 언급되는 단어가 있다. 바로 '쿠키'이다. 이 단락에서 세션과 쿠키에 대해서 알아보자.
쿠키
쿠키란?
- 쿠키는 클라이언(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 파일이다.
- 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저를 닫더라도 인증이 유지된다.
- 쿠키는 클라이언트의 '상태정보'를 로컬에 저장했다가 참조한다.
- 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시 Request Header에 넣어 자동으로 서버로 전송한다.
쿠키의 구성 요소
- 이름 : 쿠키를 구별하는 이름
- 값 : 쿠키의 이름과 관련된 값
- 유효시간 : 쿠키의 유효시간
- 도메인 : 쿠키를 전송할 도메인
- 경로 : 쿠키를 전송할 요청 경로
쿠키의 동작방식
- 클라이언트가 페이지를 요청
- 서버에서 쿠키 생성
- HTTP 헤더에 쿠키를 포함시켜 클라이언트에게 응답
- 브라우저가 종료돼도 유효시간이 남아있다면 로컬에서 보관
- 같은 요청을 할 경우 HTTP 헤더에 쿠키를 담아 요청을 보냄
- 서버에서 쿠키를 읽어 상태 정보를 변경할 필요가 있다면 쿠키를 업데이트하여 변경된 쿠키를 HTTP 헤더에 담아 응답을 보냄
세션
세션이란?
- 세션은 쿠키를 기반으로 하고 있지만, 쿠키와 달리 세션은 사용자 정보를 서버측에서 관리한다.
- 서버에서는 클라이언트마다 세션ID를 부여하여 브라우저가 종료할 때 까지 인증상태를 유지한다.
- 클라이언트가 Request를 보내면, 서버 엔진이 클라이언트에게 유일한 ID를 부여하는데 이게 세션 ID 이다.
- 접속시간에 제한을 두어 일정 시간 응답이 없으면 세션 정보가 유지되지 않게 설정이 가능하다.
- 사용자 정보를 서버에서 관리하기 때문에 쿠키보다 보안 측면에서 좋지만, 클라이언트가 많아질수록 서버 메모리를 많이 잡아먹는 문제가 있다.
- 위의 문제는 동접자가 많은 사이트에서 성능 저하의 요인이된다.
세션의 동작방식
- 클라이언트가 서버에 접속시 세션ID를 발급받음
- 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 있음
- 클라이언트는 서버에 요청할 때, 쿠키의 세션 ID를 같이 서버에 전달해서 요청
- 서버는 세션ID를 전달받아 세션에 있는 사용자 정보를 가져와서 사용
- 사용자 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답
세션의 특징
- 각 클라이언트에게 고유 ID를 부여
- 세션 ID로 클라이언트를 구분하여 클라이언트의 요구에 맞는 서비스를 제공
- 보안 면에서 쿠키보다 좋음
- 사용자가 많아질수록 서버 메모리를 잡아먹음
쿠키와 세션의 차이
- 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷하다. 그 이유는 세션도 결국 쿠키를 사용하기 때문이다.
- 가장 큰 차이점은 사용자 정보가 저장되는 위치이다. 쿠키는 로컬, 세션은 서버에 저장된다.
- 보안 면에서 세션이 쿠키보다 우수하지만, 요청 속도는 쿠키가 더 빠르다. 그 이유는 세션은 서버의 별도 처리가 필요하기 때문이다.
- 쿠키는 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있기 때문에 보안에 취약하지만 세션은 쿠키를 이용하여 세션ID만 저장하고 이것을 이용하여 서버에서 처리하기 때문에 비교적 보안성이 좋다.
- 쿠키는 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 만료시간이 되지 않았다면 계속해서 정보가 남아있을 수 있다.
- 세션도 만료시간을 정할 수 있지만 브라우저 종료시에 만료시간과 관계없이 삭제된다.
세션이 좋은거 같은데 왜 쿠키도 사용될까?
보안측면에서 세션이 쿠키보다 좋은것은 사실이다. 하지만 세션은 서버의 메모리를 차지하기 때문에 접속자가 많아지면 서버의 성능 저하를 유발한다. 이를 방지하기 위해 쿠키가 사용되기도 한다.
근데 왜 세션 과 쿠키를 사용할까?
위에서 세션과 쿠키의 특징, 장단점을 살펴보았다. 근데 대체 왜쓸까?
다시 말하지만 세션과 쿠키는 사용자의 정보를 저장하고 있다. 웹은 기본적으로 상태를 저장하지 않는 프로토콜이다. 그렇기에 세션과 쿠키가 없다면 현재 페이지에서 다른 페이지로 넘어가면 초기화된 상태일 것이다. 즉, 매 페이지마다 로그인을 진행해야 한다는 것이다.
사용자의 상태 유지를 위해 세션과 쿠키는 꼭 필요하다.
특히 쿠키의 경우 장바구니와 같은 정보를 저장하고 있는 경우가 꽤 있다. 사이트를 나가면 장바구니가 다 없어진다면 얼마나 허무할까?
또한 쿠키를 이용하여 사용자의 활동을 추적하고 분석할 수 있어 개인화된 경험을 제공해 줄 수 있다. 그렇다고 물론 "모든 쿠키 허용"을 하라는건 아니다.
토큰 기반 인증
쿠키는 보안측면에서 살짝 아쉽고, 세션은 서버의 메모리를 잡아먹는다는 단점이 있다.
이러한 단점들을 보완하기 위해 토큰 방식의 인증이 대두되었으며 가장 유명하고 많이 사용하는 JWT에 대해서 알아보겠다.
JWT는 Jason Web Token의 약자로 전자 서명 된 URL-safe(url로 이용할 수 있는 문자로 구성)한 JSON이다.
JWT는 HEADER, PAYLOAD, SIGNATURE 로 나눠져 있다.
Header
- 헤더에서는 해시 알고리즘과 토큰의 타입을 정의할 수 있다.
- HS256은 HMAC SHA 256을 의미하며 해시 알고리즘 중 하나이다.
- 타입의 값인 JWT는 이 토큰의 타입을 JWT로 지정한다.
PAYLOAD
- PAYLOAD에서는 전달하는 데이터를 포함할 수 있다.
- PAYLOAD에 들어갈 정보들을 'claim'이라 부른다
- claim에는 '등록된 claim', '공개 claim', '비공개 'claim' 3가지의 종류가 있다.
- 등록된 claim은 사전 정의 되어있으며 필수 사용은 아니지만 강력하게 사용이 권고되는 것들이다. 이 곳 에서 확인 가능하다.
- 공개 claim은 사용자 마음대로 쓸 수 있지만 충돌 방지를 위해 이 곳에 정의된 대로 사용하는게 좋다. 그렇지 않다면 URI 형식으로 키를 정해야 한다.
- PAYLOAD는 서명된 파트가 아니기에 누구든지 정보를 열람할 수 있으므로 비밀번호와 같은 중요 정보들은 담으면 안된다.
VERIFY SIGNATURE
- 이는 서명으로 header와 payload 그리고 사용자가 정한 secret 코드가 들어가야 한다.
JWT 동작 방식
- 클라이언트가 로그인을 함 (인증)
- 서버에서 클라이언트에게 AccessToken과 RefreshToken을 만들어서 응답해줌
- 클라이언트는 API 요청시에 발급받은 AccessToken을 이용하여 요청함
- 만약 AccessToken이 만료되었다면 RefreshToken을 이용하여 AccessToken을 재발급 받음
+) AccessToken을 이용하여 인가 과정을 거친 후 정보에 접근이 가능한지 판단한다.
OAuth
OAuth는 소셜로그인이다.
위는 무신사의 로그인 화면이다. 무신사 서비스 자체 아이디와 비밀번호를 통해 로그인을 하는 방식 외에 카카오와 Apple을 이용하여 로그인을 진행 할 수 있는데, 이게 바로 OAuth를 이용한 로그인 방식인 것이다.
OAuth란?
OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로 사용되는, 접근 위임을 위한 개방형 표준이다. (위키백과)
위의 무신사 로그인 화면 사진을 예시로 들어보자면 외부 어플리케이션(무신사)는 사용자 인증을 위해 카카오와 Apple의 사용자 인증 방식을 사용한다. 이때, OAuth를 바탕으로 제 3자 서비스(무신사)는 외부 서비스(카카오, 애플)의 특정 자원을 접근 및 사용 할 수 있는 권한을 인가 받게 된다.
OAuth 참여자
OAuth 동작에 관여하는 참여자는 크게 세 가지로 구분할 수 있다.
- Resource Server : Client가 제어하고자 하는 자원을 보유하고 있는 서버
- 구글, 애플, 카카오, 네이버가 이에 해당한다.
- Resource Owner : 자원의 소유자이다.
- Client가 제공하는 서비스를 통해 로그인하는 실제 유저가 이에 속한다.
- Client : Resource Server에 접속해서 정보를 가져오고자 하는 클라이언트 (웹 어플리케이션) 이다.
소셜 로그인을 구현해 보는건 추후 다른 글을 통해 코드와 함께 포스팅 하겠습니다.