[F-Lab 모각코 챌린지 33일차] 쿠키, HTTP 기본 인증

부추·2023년 7월 3일
0

F-Lab 모각코 챌린지

목록 보기
33/66

TIL

  1. 쿠키!
  2. 인증과 인가의 차이
  3. HTTP 기본 인증이란?
  4. 다이제스트는?



1. Cookie

웹에서 말하는 쿠키란, 서버가 클라이언트에게 보내는 작은 데이터 조각이다.

이 조각은 서버가 여러 클라이언트들을 구분하는데 사용되기도 하고, 쿠키를 키값으로 서버 세션을 관리하기도 하고(비슷한 얘기인가ㅎ), 서버에서 사용하는 간단한 클라이언트 데이터를 저장하기도 한다. 쿠키는 클라이언트 쪽(일반적으로 브라우저)에 저장되는 만큼 서버쪽보다 보안에 취약하기 때문에 짧고 간단하며 민감하지 않은 정보들이 들어있다는 특징이 있다.

쿠키는 기본적으로 키-값 쌍이다. 브라우저가 여러 사이트를 돌면서 각 사이트 서버의 쿠키를 가지기 때문에, 서버 입장에서 사용할 수 있는 쿠키들이 구분되어야하기 때문에 키가 존재해야한다. 서버가 클라이언트에게 쿠키 데이터를 보내고, 지정된 path에서 쿠키를 사용하도록 지시하기 위해선 응답 객체의 Set-Cookie헤더를 사용하면 된다.


아래는 크롬 개발자도구를 통해 무신사 스토어의 HTTP 응답 메세지 헤더의 Set-Cookie 항목을 뽑아온 것이다. 실제 쿠키 데이터 PHPSESSID=어쩌구, 해당 쿠키가 사용될 url path값인 path=/, 그리고 현재 사이트 주소인 domain값이 지정되어있다. 참고로 도메인 값이 .으로 시작되는 것은 musinsa.com 하위 도메인 모두가 해당 쿠키 값을 이용할 것이라는 의미이다.
음.. 쿠키 값은 털려도 상관 없겠지? 모자이크 귀찮아서 안한다.


스프링 http 서블릿의 Cookie 클래스를 이용하면 손쉽게 쿠키 객체를 만들 수 있다. 같은 서블릿 클래스인 HttpServletResponseaddCookie() 메소드를 이용해서 응답 헤더에 쿠키를 추가해줄 수도 있다.

코드를 보자!

@RestController
@Slf4j
@RequestMapping("/cookie")
public class CookieController {
    @GetMapping("/set")
    public ResponseEntity<String> setCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie("myCookie","delicious!");
        cookie.setMaxAge(3600);
        cookie.setPath("/cookie");

        response.addCookie(cookie);
        return ResponseEntity.ok().body("쿠키가 생성되었습니다!");
    }
}
  • new Cookie() 생성자를 통해 쿠키 이름(name)이 myCookie, 값(value)이 delicious!인 쿠키를 생성했다. 클라이언트 브라우저가 가지고 있는 쿠키는 이렇게 키-값 쌍으로 존재한다.
  • cookie.setMaxAge() : 생성된 쿠키의 만료 시간을 초 단위로 지정한다. myCookie:delicious! 쿠키는 1시간 뒤에 삭제될 것이다.
  • cookie.setPath() : 생성된 쿠키가 적용될 url path를 지정한다. 인자로 주어진 path는 쿠키가 사용될 path의 prefix가 된다. 위 코드에선 /cookie를 prefix로 지정했으므로 /cookie 하위의 path에서는 방금 생성한 쿠키가 전부 사용된다.
  • 서블릿 응답 객체의 addCookie()메소드를 사용하여 응답 헤더에 Set-Cookie 항목을 설정했다.

이제 서버를 켜고 localhost:8080/cookie/set에 접속해보자. 크롬 개발자도구를 이용해 응답 메세지의 헤더를 다시 뽑아봤다.
오오... 무신사 사이트를 들어갔을 때랑 비슷한 포맷이다. Max-AgeExpires 항목은 내가 쿠키를 설정할 적에 setMaxAge()를 지정했기 때문이다. 또한 domain항목이 없는 것은 아직 배포된 서버 호스트가 존재하지 않기 때문이다..!


아무튼 사용자가 쿠키를 사용하게 하기 위해서 Set-Cookie헤더가 어떻게 사용되는지, 그리고 spring에서 실습까지 마쳤다.




2. 인증과 인가에 관하여!

1) Authentication / Authorization ?

너는 누구니? / 너 여기 올 수 있니? 의 차이이다.

인증, 즉 Authentication은 아주아주 간단히 말하면 "로그인"이다. 서버 입장에서 현재 요청을 시도하는 사용자가 누구인지 식별하는 것이다. 인증을 통해 사용자는 익명이 아닌 식별 가능한 개체가된다. 웹 서버에서는 사용자 로그인 후 로그인 정보를 세션에 남겨두거나, JWT 토근을 발급하는 식으로 사용자 인증 정보를 저장한다.

인가, 즉 Authorization은 "자격 권한 증명"이다. 서버의 특정 리소스에 접근하거나 어떤 기능을 수행하려 할 때 사용자가 가진 권한을 기반으로 해당 동작이 가능한지 확인하는 과정이다. 적절한 인가 과정을 거치지 않으면 민감한 정보에 권한이 없는 모든 사용자가 접근하여 데이터의 보안이나 무결성이 깨질 수 있다.


2) HTTP 기본 인증?

HTTP 기본 인증이란, HTTP 프로토콜 컨텍스트에서 사용자를 인증하는 데 사용되는 간단한 인증 매커니즘이다. 기본적인 선에서 HTTP가 권한이 없는 사용자에 대한 접근을 제어하기 위해 제공한다.

HTTP 기본 인증이 이뤄지는 과정은 다음과 같다!

  1. 사용자의 GET 요청 : 접근 권한이 없는 리소스에 요청
  2. 서버의 401 Unathorized 응답 : 헤더의 WWW-Authenticate 항목과 함께 사용자 인증을 요구하는 응답을 보낸다. 항목 값에는 사용할 인증 체계를 지정한다. 현재의 경우, HTTP 기본 인증이므로 Basic 값이 존재한다.
  3. 사용자의 인증 정보 전송 : 사용자는 재요청 헤더의 Authorization 항목에 서버에서 지정한 인증 체계와 더불어 base64로 인코딩된 username:password쌍을 담아 전송한다.
Authorization: Basic base64(username:password)
  1. 서버의 유효성 검사 및 사용자 접근 결정 : 사용자가 보낸 username:password쌍을 통해 사용자 인증이 통과되고 인가가 통과되면 서버는 사용자의 리소스 접근을 허용하고 200 ok 응답을 보낸다.

3번 과정에서, base64로 인코딩된 아이디-비밀번호 쌍은 HTTP를 이용하지 않았을 경우 보안에 매!! 우!! 취약해진다. 물론 오늘날에 와서 HTTP 기본 인증만을 이용해서 민감한 정보에 인증 및 인가를 진행하는 사이트는 거의 없겠지만, 기본 인증 매커니즘을 쓸 땐 TLS 과정을 포함하는 HTTPS를 쓰는 것이 좋다.


3) 다이제스트?

HTTP 기본 인증에서 한걸음 더 나아간 인증/인가 매커니즘이다. HTTP 기본 인증에서 사용자의 Authorization 항목은 중간에 탈취당하면 끝이다. username과 password가 그대로 노출되어버린다. 이를 개선하기 위해 다이제스트는 username:password의 base64인코딩 결과값 대신 해시값을 인증에 사용한다. 해시란 가변길이의 인풋을 고정길이의 아웃풋으로 매핑하는 비가역 함수이다.

그런데 여전히 문제는 남아있다. 요청 패킷이 탈취되어도 username:password의 원문이 털리지 않는다는 장점이 있지만, 해커가 그대로 다이제스트값을 이용해 위조 요청을 보내버리면 소용이 없다. 비밀번호 원문을 모르더라도, 비밀번호로 사용되는 무언가를 알면 끝이기 때문이다. 이를 방지하기 위해 다이제스트에선 서버가 'Nonce'라는 항목을 클라이언트에게 보낸다.

nonce란? 이해하기 쉽게 설명하면 해시 인풋값에 대한 salt라고도 볼 수 있다. 매 ms마다 달라지기 때문에 nonce를 비밀번호에 섞으면 nonce가 바뀔 때마다 다이제스트도 바뀌게 된다. 서버는 사용자에게 인증을 하라는 명령을 보낼 때 생성된 Nonce값을 전달한다. 클라이언트는 이 nonce값과 함께 아이디 비밀번호를 해시화해서 서버에 보낸다. 서버는 이 값을 이용해서 "현재" 사용자가 유효함을 확인한다.

시시각각 변하는 server-generated Nonce 덕분에 현재 다이제스트 인증에 사용된 클라이언트의 다이제스트 값은 다음 인증에 재사용될 수 없다.


그림과 함께 다이제스트 인증이 진행되는 과정을 정리하자! 그림에서 "요약"은 해시 결과값, 즉 다이제스트라고 생각하면된다.

  1. 사용자의 GET 요청 : 접근 권한이 없는 리소스에 요청
  2. 서버의 401 Unathorized 응답 : 헤더의 WWW-Authenticate 항목과 함께 사용자 인증을 요구하는 응답을 보낸다. 항목 값에는 사용할 인증 알고리즘, Nonce, realm 등이 존재한다.
  3. 사용자의 인증 정보 전송 : 사용자는 재요청 헤더의 Authorization 항목에 지정된 알고리즘을 사용하여 username:password와 nonce 값을 더한 값의 다이제스트를 넣는다.
  4. 서버의 유효성 검사 및 사용자 접근 결정 : 사용자가 보낸 다이제스트를 통해 사용자 인증이 통과되고 인가가 통과되면 서버는 사용자의 리소스 접근을 허용하고 200 ok 응답을 보낸다.



REFERENCE

https://straw961030.tistory.com/118
http://iloveulhj.github.io/posts/http/http-basic-auth.html

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글