인증(Authentication)과 인가(Authorization)

Joon·2021년 11월 22일
0
post-custom-banner

참고

https://bcho.tistory.com/955
https://interconnection.tistory.com/74
https://cjh5414.github.io/cookie-and-session/
https://velopert.com/2350

로그인 서비스를 구현하려고 애쓰던 와중 쿠키,세션,JWT,OAuth등을 공부하기 전에, 알아야할 기본 지식인 인증과 인가에 대해 먼저 알아보자.

인증(Authentication)

로그인을 예시로 들자면 인증은 userId, password와 같은 정보로 해당 웹 서비스의 회원인지 아닌지를 '입증'하는 과정이다.
즉, 식별 가능한 정보들로 서비스에 등록된 유저의 신원을 입증하는 과정이다.
이는 서비스 뿐만이 아닌 API 또한 마찬가지로, API를 호출하는 대상 (그것이 단말이 되었건, 다른 서버이건, 또는 사용자이던간에)을 확인하는 절차가 필요하다. 이를 API인증이라고 한다.

인가(Authorization)

반면에 인가는 인증을 바탕으로 한다. 어떠한 리소스에 대해 어느 사용자가 그 리소스를 요청(request)했을 때, 해당 사용자가 그 리소스를 사용할 권한이 있는지를 체크하는 과정이다. 따라서 인가란
인증된 사용자에 대한 자원(resource) 접근 권한을 확인하는 작업이다.

인증과 권한 부여(인가)의 방법

인증과 인가는 자원을 적절하고 유효한 사용자에게 전달하거나 공개하기 위한 조치이며, 이를 구현하기 위한 방법은 크게 5가지가 있다. (로그인을 예시로 든다.)

1. 인증(로그인) 하기 -Request Header를 이용한 방법
2. 인증(로그인) 유지하기 - Browser를 이용한 방법
3. 안전하게 인증하기(로그인) - Server를 이용한 방법
4. 효율적으로 인증하기(로그인) - Token을 이용한 방법
5. 다른 채널을 통해 인증하기(로그인) - OAuth를 이용한 방법

배경지식


먼저 위의 5가지 방법들을 살펴보기 전에, 앞서 https://velog.io/@dev-joon/HTTP%EC%99%80-HTTPS HTTP관련 포스트에서 알아보았던 HTTP의 무상태성(stateless) 특성에 대해 알고 넘어가야 한다. 이 위의 5가지 인증과 권한 부여가 애초에 필요한 이유이자 배경이 바로 이 특성이기 때문.
HTTP의 무상태성은 비연결성에서 파생된 특성으로, 클라이언트와 서버가 요청과 응답을 한번 마치고 나면, 맺었던 연결을 그 어떠한 기억없이 끊는 특성에서 비롯된 특성이다. 따라서 서버는 같은 클라이언트가 연속으로 요청을 보내도, 같은 클라이언트라는 인식이나 기억이 없이 응답을 보낸다. 이는 로그인과 완전히 상반되는 개념으로, 적어도 '로그인'이라는 기능에 있어서 도움이 되지 않는 특성이다. 따라서 이를 극복하기 위해 도입된 개념들이 바로 인증(Authentication)과 인가(Authorization)이며 그를 구현하기 위한 방법이 바로 위의 5가지 방법이다.

Request Header를 이용한 방법(HTTP Basic Auth)

가장 기본적이고 단순한 형태의 인증 방식으로 사용자 ID와 password를 HTTP Request Header에 Base64 Encoding 형태로 넣어서 인증을 요청하는 방식이다. 이 인코딩은 브라우저가 처리한다.


클라이언트의 브라우저가 Base64를 통해 인코딩형태로 Request Header에 넣어 요청을 하면, 서버에서는 이를 디코딩해서 DB에 접근하여 확인하고 OK를 보내는 형식으로 진행이 된다.

단점

하지만, 이런식으로 인증(로그인)을 하면 몇가지 문제점이 생긴다.
1. 만약 중간에 해커가 데이터 패킷을 가로채서 이 헤더를 Base64로 디코딩을 한다면 사용자의 ID와 password가 그대로 노출된다. 따라서 이 방식을 사용하려면 네트워크 레벨의 암호화를 사용하는 것이 권장된다. 주로 HTTP의 네트워크 레벨 암호화는 HTTPS 기반의 보안 프로토콜이 이용되며, SSL을 통해 해커들이 중간에 이 네트워크 통신을 감청할 수 없도록 해준다.

  1. 로그인한 상태에서 어떠한 새로운 Request(새로운 글을 쓴다던가, 수정을 한다던가)를 할때마다 매번 인증해야한다.

첫번째 문제점을 해결하기 위해 나온 인증 프로토콜이 Digest access Authentication이라는 프로토콜이다.

Digest access Authentication

참고 : https://en.wikipedia.org/wiki/Digest_access_authentication
좀 복잡하기 때문에 다음에 제대로 살펴보자

두번째 문제점: 매번 인증해야 함에 대한 해결책은 한번 로그인(인증)을 할 경우, 어떠한 방식에 의해 그 사용자에 대한 인증(Authentication)이 유지되면 된다.
그리고 이를 위한 방법이 바로 쿠키이다.

먼저 쿠키가 무엇인지에 대해 알아보자.

쿠키란?

  • 브라우저 로컬 스토리지에 저장되는, Key:Value로 구성되며 String으로 이루어진 작은 데이터 파일이다.
  • 하나당 최대 4KB의 크기로 저장되며, 클라이언트에 300개까지 쿠키저장이 가능하다.
  • 쿠키의 구성 요소:
    • 이름: 각 쿠키의 식별 시 필요한 이름
    • 값: 쿠키의 이름과 관련된 값
    • 유효시간: 쿠키의 유지시간
    • 도메인: 쿠키를 전송할 도메인
    • 경로: 쿠키를 전송할 요청 경로
  • 쿠키의 동작 방식
    1. 클라이언트가 페이지를 Request하면 서버에서 쿠키를 생성한다.
    2. 서버가 응답할 때 쿠키에 저장할 정보를 Response Header의 Set-Cookie로 함께 전달한다.
    3. 브라우저가 종료되더라도 쿠키 만료 기간이 유효하다면 클라이언트에서 보관하고 있는다.
      • 만약 브라우저가 종료도더라도 쿠키를 유지하고 싶다면 Permanant를 이용하면 된다. Permanant는 쿠키 생성 시 ExpiresMax-Age옵션으로 추가하면 이용 가능하다.
      • Expires: 쿠키가 만료될 날짜 지정
      • Max-Age: 현재시간 기준, 얼마나 오래 유지시킬 것인지 지정
    4. 클라이언트가 요청을 할 경우 HTTP Request Header에 Cookie: key=value로 쿠키를 함께 보낸다.

용도

쿠키의 존재로 여러 페이지를 이동하거나 서버에 새로운 요청을 할 때마다 매번 로그인(인증)을 하지 않고 유저 정보를 유지할 수 있다.
대표적인 사용처로는
1. ID 저장, 로그인 상태 유지
2. 광고 7일간 다시 보지 않기
3. 최근 검색 상품 추천
4. 쇼핑몰의 장바구니 기능
등이 있다.

단점

다만 이런 식으로 인증을 하고 유지할 경우, 클라이언트에게 편리함을 제공해주지만, 해커들에게도 매우 편리하게 유저 정보를 제공하게 된다. 해커들이 쿠키만 탈취하면 유저 정보를 쉽게 빼낼 수 있기 때문이다.

Server를 이용한 방법(Session)

이렇듯 서버에 비해 상대적으로 보안적인 부분에서 취약한 클라이언트를 보완하기 위해 Session을 활용하여 서버의 도움을 받는다.

세션이란 무엇인지 알아보자.

세션이란?

  • 쿠키를 기반으로 하지만, 유저 정보를 로컬 스토리지와 브라우저에 저장하는 쿠키와 달리, 세션은 서버에서 관리한다. 따라서 보안적인 측면에서 일반적인 쿠키보다 우수하다.
  • 서버는 클라이언트들을 식별하기 위해 세션 ID를 각각 부여하며 웹 브라우저가 서버에 접속해서 종료할 때까지 인증상태를 유지한다.
  • 접속시간에 제한을 두어 일정 시간동안 응답이 없을 시, 정보가 삭제되도록 설정이 가능하다.
  • 클라이언트가 요청을 보내면, 해당 서버가 클라이언트에게 식별 ID를 부여하는데 이를 세션ID라고 한다.

  • 세션의 동작 방식
    1. 클라이언트가 서버 요청시 세션 ID를 부여받는다.
    1. 해당 세션 ID에 대해 클라이언트는 쿠키로 저장하여 보관하고 있는다.
      Set-Cookie: SESSIONID==blahblahblah
    2. 클라이언트의 요청 시, 쿠키에 저장된 세션 ID를 같이 전달하여 요청한다.
    3. 서버는 쿠키에 저장된 세션 ID를 전달 받아 해당 ID를 통해 클라이언트 정보를 가져와서 사용하여 요청을 처리후, 클라이언트에게 응답한다.

단점

  • 여러 서버를 지닌 웹 서비스의 경우, 세션 ID 관리면에서 문제가 생긴다. 세션ID는 각각의 서버에서 개별적으로 관리하는 정보이기에 세션만을 관리하는 세션 스토리지 서버가 따로 필요하다.
    • 유저 정보를 클라이언트가 아닌 서버에서 관리하기에 보안 면에서 뛰어나지만, 사용자가 많아지면 서버 메모리를 많이 차지하여 서버 과부하와 성능 저하의 원인이 될 수 있다. 또한 유저가 너무 많을 경우, 세션 스토리지가 감당을 못하고 터질 수도 있다. 이는 모든 정보를 세션을 활용하여 서버에 저장하는 것이 아닌, 일부 가벼운 정보의 경우 쿠키를 활용하게 되는 이유가 된다.

쿠키와 세션의 차이점

쿠키(Cookie)와 세션(Session)은 목적이 같으며, 동작원리 또한 매우 유사하다. 세션이 쿠키를 기반으로 하기 때문이다. 다만 그 둘의 가장 큰 차이점이라고 한다면, 유저의 정보가 저장되는 위치이다.
쿠키는 브라우저의 로컬 스토리지에 정보를 저장하며, 세션은 서버의 자원을 빌려 서버에 저장한다.
따라서 보안 면에서 세션이 더 우수하며, 요청 속도 면에서는 세션이 서버의 처리를 요하기에 쿠키가 세션보다 우수하다.
만료 시간, 유효 시간의 관점에서 보자면, 쿠키는 파일로 저장되기에 브라우저를 종료해도 계속해서 정보가 남아있을 수 있다. 하지만, 세션은 만료시간을 지정해도 브라우저가 종료되는 즉시 삭제된다.

각각의 문제점


위에서 언급한 5가지 해결책 중, 1,2,3의 세가지 해결책을 통해 사용자의 정보를 각각 브라우저(Cookie), 서버(Session), DB(Session DB)에게 맡겨 인증을 하고 인증을 유지해보았다.
하지만 각각에게는 보안의 문제점, 서버 과부하의 문제점 등 또 다른 문제점들이 발생하였고, 이 세가지 해결책은 서버, 클라이언트, 세션 저장소가 사용자가 정보를 지니고 있다는 점에서 HTTP의 무상태성(Stateless)이라는 기초적인 통신 기반을 상태성(Stateful)으로 바꾸는, 두가지의 패러다임이 충돌하는 현상이 발생한다.

확장성의 문제
여기서 확장이란, 단순하게 서버의 사양을 업그레이드하는 것 뿐이 아닌, 더 많은 트래픽을 감당하기 위해 여러개의 프로세스를 돌린다던가, 여러 대의 서버 컴퓨터를 추가하는 것을 의미한다.

CORS(Cross-Origin Resource Sharing)의 문제
쿠키는 설계상, 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있기에 여러 도메인에서 관리하기가 매우 번거롭다.

![](https://images.velog.io/images/dev-joon/post/90537681-9e24-4c8e-9cd8-fd390b236304/image.p
우리는 위에서 왼쪽에 위치한 클라이언트와 오른쪽에 위치한 서버에게 각각 사용자 정보를 맡겨보고, 그에 따르는 문제점이 발생함을 알았다. 그렇다면,

정보의 흐름에 해당하는 화살표에 정보를 맡겨보는 것은 어떨까?
정보의 흐름이란 요청과 응답을 의미한다. 요청과 응답에 사용자의 상태를 담아보는 시도를 해보자. 이는 다음 포스트에서 정리를 해보자.

profile
한줄씩 완성해가는 개발 공부
post-custom-banner

0개의 댓글