인증과 인가

heauchi·2024년 10월 25일

When I Was Mentee - Front

목록 보기
21/21
post-thumbnail

서비스를 만들때 우리는 모두가 안전하게 개발중인 서비스를 사용하기를 원합니다. 인증과 인가는 자원을 "적절한, 유효한" 사용자에게 전달 혹은 공개하기 위한 방법입니다.

인증과 인가에 대해 알아보면서 어떻게 사용자를 인증하고 사용자가 리소스에 접근하는것을 인가할 수 있는지에 대한 플로우와 방법론들을 알아보도록 하겠습니다.


🔐인증과 인가란 무엇인가?

인증과 인가의 정의와 예시는 다음과 같이 들수있습니다.

정의예시
인증 (Authentication)식별 가능한 정보로 서버에 등록된 유저의 신원을 입증하는 과정학생증 안에 있는 증명사진으로 내가 학생증 안에 있는 학생임을 입증할 수 있다.
인가 (Authrization)인증된 사용자의 자원접근권한을 확인하는 과정학생증으로 기숙사에는 들어갈 수 있지만, 교수님의 연구실 출입증으로 사용할 수 없다.

간단하게 인증은 사용자를 식별하는 과정, 인가는 식별된 사용자에게 주는 자원접근 권한입니다. 인가를 받기 위해서는 인증이 선행되어야 합니다.

인증 ➡️ 인가

다음은 인증의 방법론입니다. 인증과 인가의 개념에 대해서 알았다면, 방법론을 알아보고 인증과 인가가 필요한 프로젝트에 적용할 수 있으면 좋을것 같습니다.


🪪Request Header로 인증하기

const instance = axios.create({
	baseURL: '',
	headers: {
		Authrozation: 'userid:userpasswd',
	}
})

이런 식으로 Request Header에 요청을 담아서 보내게 되면 브라우저는 Base64 인코딩 방식으로 userid:userpasswd라는 텍스트를 파싱해서 인코딩 하고 요청헤더의 Authrization 값에 넣어서 보내줍니다.

서버에서는 그 값을 체크해서 DB와 대조해본 뒤에 똑같은 값이 있으면 서버에서 OK 사인을 보내주면 인증이 완료됩니다. 하지만 Request Header 만 사용하게 되면 사용자가 계속 인증요청을 해주어야하는 문제가 있습니다.
이러한 문제를 해결하기 위하여 브라우저로 인증을 유지해줍니다.


🌐브라우저로 인증 유지하기

브라우저에 있는 스토리지의 힘을 빌려서 인증을 유지해주는데, 쿠키에 아이디와 비밀번호를 집어넣고 사용자가 인증이 필요한 요청을 할 때 같이 넣어서 보내줍니다.
그러면 체크를 하고 원하는 자원을 받을 수 있습니다. 편하게 사용을 할 수 있지만, 스토리지에 생으로(raw하게) 사용자 정보가 담겨있으므로 해커에게 너무나도 좋습니다. 클라이언트가 서버보다 보안에 취약하기 때문에 서버를 통해서 보안의 향상이 필요합니다.


🤵서버로 안전하게 인증하기

🎫세션

보안을 강화하기 위해서 서버에 요청을 하는데 어떤 방법을 사용할까요? DB와 대조를 하는 작업까지는 똑같은데 원하는 자원을 바로 내보내주는 것이 아니라 인증된 사용자의 식별자와 랜덤한 아이디를 생성해서 이 응답을 헤더로 넘겨주어 클라이언트(브라우저)가 저장할수 있도록 만들어줍니다. 이러한 방법을 세션 방식이라고 합니다.
세션은 다음과 같은 장점이 있습니다.

세션의 장점

  1. 사용자의 raw 한 데이터를 가지고 있지 않으므로 해커가 정보를 가지고 가더라도 크게 위험하지 않습니다.
  2. 세션의 만료기한을 정할 수 있기때문에 해커가 세션정보를 가지고가더라도 일정 시간이 지나면 유효하지 않게 되어 위험하지 않습니다.
  3. 탈취당한 세션을 해커가 이용하더라도 세션을 파기할 수 있기 때문에 또 안전합니다.

사용자가 클라이언트에 저장된 세션으로 요청을 하게 되면 서버에서 DB와 대조하지 않고 인증되었다는 사인을 보내주기때문에 DB까지 가지 않고 인증을 진행할 수 있습니다.

💿세션 스토리지

하지만 문제는 서비스가 커지고 여러개의 서버를 두면서 로드밸런싱(어떤 서버로 보내야 부하가 적은가) 을 하며 발생합니다.
서버 각각에서 발급된 세션을 관리하기 때문에 서버에서 받은 세션을 동기화하는 작업을 거쳐야합니다.

예를들어

1번서버에서 인증을 받아 세션을 받고, 받은 세션으로 다음 요청을 2번서버에서 하면?
➡️발급한 세션은 1번에 들어있기 때문에 2번 서버는 요청을 거부합니다.

이러한 문제를 세션스토리지를 두어 해결할수 있습니다.
세션스토리지란 사용자들의 세션정보를 저장해두는 서버측 저장소로 1번 서버에서 세션을 발급받았다면, 그 세션내용을 세션스토리지에 저장하여 2번, 3번 서버도 그 내용에 접근할 수 있도록 만듭니다.
이것도 문제가있는데 클라이언트가 엄청 많으면 계속 인증요청을 보내고 세션스토리지를 담당하는 DB가 과부화가 걸리게 됩니다.


🪙토큰으로 효율적으로 인증하기

클라이언트, 서버 다 문제가 생기니까 정보의 흐름에 요소를 담을수 있게 하면 어떨까? 정보의 요청과 응답 안에 상태를 담아서 인증과 인가를 처리하면 어떨까? 라는 아이디어로 토큰의 개념이 나오게 되었습니다.
토큰은 Json Web Token을 가장 많이 사용하고 자세한 내용은 블로그 다른글에서 다룹니다 :)
Json Web Token에 대해서 알아보자


👽OAuth로 인증하기

우리 서버에서 인증과정을 거치지 않고 인가를 받는것이 가능하다면 믿으시겠나요? 대규모 서비스에서 인증을 받고 우리 서버에서 필요한 서비스를 제공하는 것이 가능합니다. 이렇게 다른 웹사이트 상에서 자신들의 정보에 대한 접근권한을 부여할 수 있는 공통적인 수단을 OAuth라고 하는데 구글, 네이버, 카카오인증... etc OAuth에 대한 자세한 내용은 블로그 다른 글에서 다룹니다 :)
OAuth에 대해 알아보자

참고문헌

▶️우아한 테코톡 인증과 인가 - 토니
▶️우아한 테코톡 인증과 인가 - 후추
▶️우아한 테코톡 인증과 인가 - 루피

0개의 댓글