Home

Published

- 14 min read

[ Security ] 인증(Authentication)과 인가(Authorization)

img of [ Security ] 인증(Authentication)과 인가(Authorization)

들어가며

보안에 대해 공부한다고 했을 때, 가장 먼저 알아야 하는게 인증과 인가이다. 인증과 인가를 헷갈리는 경우가 있는데 이번 기회를 통해 인증과 인가의 차이에 대해 확실하게 알고 넘어가자.

인증(Authentication)

보호된 리소스에 접근하는 것을 허용하기 전에 이전에 등록된 유저의 신원을 인증(validating)하는 과정이다.

인가(Authorization)

요청된 리소스에 접근할 수 있는 권한이 있는 인증(authenticated)된 유저인지 입증(validating)하는 과정이다.

다시 말해, 1차적으로 인증을 통해 유저를 검증하고, 리소스에 대해 유저가 접근할 수 있는지 입증하는 과정이 인증과 인가이다.

사전지식

무상태성(statelessness)은 시스템이나 애플리케이션이 이전의 상태(state)를 기억하지 않고 각각의 요청을 독립적으로 처리하는 것을 의미한다. 즉, 요청 간의 연결이나 의존성이 없으며, 각각의 요청은 그 자체로 완전한 정보를 포함하고 있다.

무상태성을 가지는 시스템에서는 클라이언트가 서버에 요청을 보낼 때 필요한 모든 정보를 요청에 포함시켜야 한다. 서버는 해당 요청에 필요한 처리를 수행한 후 응답을 반환하고, 클라이언트는 필요한 경우 다음 요청을 위해 필요한 정보를 다시 제공해야 한다. 서버는 클라이언트의 이전 요청이나 상태를 기억하지 않기 때문에 서버 측에서 상태를 유지하거나 관리할 필요가 없어진다.

무상태성은 여러 가지 이점을 제공한다.

  1. 확장성: 무상태성은 시스템을 수평적으로 확장할 수 있는 기반. 각각의 요청은 독립적으로 처리되므로, 여러 서버 인스턴스를 추가하여 요청 부하를 분산시킬 수 있다.
  2. 무결성: 상태를 기억하지 않는 것은 시스템이 불필요한 상태 관리 작업을 수행하지 않아도 되므로, 무결성을 유지하는 데 도움이 됨. 각각의 요청은 자체적으로 필요한 정보를 가지고 있기 때문에 서버 측에서 상태를 수정하거나 오염시키는 일이 없다.
  3. 캐시 가능성: 무상태성은 캐싱을 적극적으로 활용할 수 있는 환경을 제공한다. 응답이 요청의 상태에 의존하지 않고 오로지 요청의 내용에만 의존한다면, 동일한 요청에 대한 응답은 캐시에 저장되어 재사용될 수 있다.

이제 무상태성에 대한 개념을 이해했으니, 다양한 인증 방식에 대해 알아보자.

인증하기 - Request Header(요청 헤더)

회원의 아이디가 user, 비밀번호가 1q2w3e!라고 하자.

   http://user:1q2w3e!@www.blog-full-of-desire.vercel.app/login

위 주소로 로그인 요청을 하면 브라우저가 처리해준다. 위 url을 Base64라는 인코더를 이용해서 인코딩을 한 후에 전달한다.

fhegjGFjgaowefjpifjdasl로 인코딩이 되었다고 하자.

   Authorization: Basic fhegjGFjgaowefjpifjdasl

그리고 위와 같은 요청 헤더에 담아서 요청해준다. 하지만 불편한 점도 있고 문제가 있다. 위 방식을 사용하게 되면 유저가 로그인할때마다 인증해야 하고, url에 개인정보를 담아 보내게 되면 보안 문제가 생긴다.(전에 학교에서 인턴연계로 갔던 회사가 있었다. 이 회사와 협업하는 회사가 위 방식으로 처리하려 했는데 지금 생각해도 어지럽다.)

이런 문제를 해결하기 위해, 브라우저를 활용한 더 안전하고 효율적인 인증 방식을 살펴보자.

인증 유지하기 - Browser(세션, 쿠키)

세션(Session)은 웹 애플리케이션에서 사용자의 상태를 유지하기 위한 메커니즘이다. 웹은 기본적으로 무상태성(statelessness)을 가지기 때문에, 클라이언트와 서버 간의 연결이 해제되면 이전의 상태 정보를 서버가 기억하지 못한다. 이때 세션을 사용하면 서버는 클라이언트에 고유한 세션 식별자를 할당하여 클라이언트의 상태 정보를 저장하고 유지할 수 있다.

일반적으로 세션은 다음과 같은 방식으로 동작한다.

세션의 동작 방식

  1. 세션 생성: 클라이언트가 서버에 처음 접속하면, 서버는 고유한 세션 식별자를 생성함. 이 식별자는 일반적으로 쿠키(cookie) 또는 URL 매개변수에 포함되어 클라이언트에게 전달된다.
  2. 세션 데이터 저장: 서버는 생성된 세션 식별자를 기반으로 클라이언트의 상태 정보를 저장한다. 이 정보는 일반적으로 서버의 메모리, 데이터베이스, 파일 시스템 등에 저장된다. 세션 데이터는 클라이언트에 대한 고유 정보(로그인 상태, 장바구니 내용 등)를 포함할 수 있다.
  3. 세션 식별자 전송: 서버는 클라이언트에게 생성된 세션 식별자를 전달한다. 일반적으로 쿠키를 사용하여 세션 식별자를 클라이언트에게 저장하고, 이후의 모든 요청에서 쿠키를 통해 세션 식별자를 서버에 전송한다.
  4. 세션 데이터 사용: 클라이언트의 후속 요청에서 서버는 세션 식별자를 받아 해당 클라이언트의 세션 데이터를 검색한다. 서버는 세션 데이터를 사용하여 클라이언트에 맞는 동작을 수행하고, 필요한 정보를 제공한다.
  5. 세션 종료: 세션은 일정 기간 동안 유지되거나, 클라이언트가 로그아웃하거나 연결을 종료할 때까지 유지된다. 세션이 종료되면 세션 데이터는 일반적으로 삭제된다.

하지만 이 방법도 문제가 있다.

세션 사용의 문제점

세션은 상태 유지와 사용자 인증에 효과적이지만, 일부 상황에서 문제가 발생할 수 있다.

  1. 확장성 제한: 사용자가 증가하면 서버 메모리 부담이 커진다. 특히 대규모 시스템에서 세션 관리가 복잡해질 수 있다.
  2. 로드 밸런싱 문제: 여러 서버를 사용할 때, 사용자 요청이 다른 서버로 전달되면 세션 정보가 없어 인증이 끊길 수 있다.
  3. CORS (Cross-Origin Resource Sharing) 이슈: 여러 도메인을 사용하는 서비스에서 세션 관리가 어려울 수 있다.
  4. 모바일 앱 지원의 어려움: 쿠키 기반 세션은 모바일 환경에서 관리가 복잡할 수 있다.

안전하게 인증하기 - 세션 DB 사용

세션의 일부 문제를 해결하기 위해 세션 정보를 데이터베이스에 저장하는 방법을 사용할 수 있다. 이 방식은 Redis와 같은 빠른 데이터베이스를 활용해 중앙 집중식으로 세션 데이터를 저장한다. 이를 통해 여러 서버가 동일한 세션 저장소에 접근하여 정보를 공유할 수 있게 된다.

이러한 방식은 시스템의 확장성을 향상시킨다. 세션 저장소를 독립적으로 확장할 수 있어 전체 시스템의 확장성이 개선되며, 한 서버가 다운되어도 다른 서버에서 세션 정보에 접근할 수 있어 장애 대응 능력도 향상된다.

하지만 세션 DB 사용에도 한계가 있어 더 효율적인 방법이 필요했다. 이에 등장한 것이 토큰 기반 인증이다.

효율적으로 인증하기 - Token(JWT)

토큰 기반 인증, 특히 JWT(JSON Web Token)를 사용하면 세션의 일부 한계를 극복할 수 있다. JWT는 서버가 클라이언트의 상태를 저장할 필요가 없는 상태 비저장(Stateless) 방식으로 동작하여 서버 부하를 줄인다.

토큰이 클라이언트에 저장되므로 서버 확장이 용이하며, 도메인에 구애받지 않아 여러 서비스 간 인증이 쉬워 CORS 문제에도 잘 대응한다. 또한 모바일 환경에서도 쉽게 구현 가능하여 모바일 친화적이다.

보안 측면에서도 장점이 있는데, 토큰에 서명을 사용하여 위조를 방지할 수 있다. 하지만 JWT도 완벽한 해결책은 아니며, 토큰 관리와 만료 처리 등에 주의가 필요하다. 하지만 JWT도 완벽한 해결책은 아니며, 토큰 관리와 만료 처리 등에 주의가 필요하다.

인가(Authorization)의 구현

앞서 살펴본 인증 방식들과 달리, 인가는 각 시스템의 요구사항과 비즈니스 로직에 따라 매우 다양한 형태로 구현된다. 인가는 시스템이 어떤 목적을 가지고 있는지, 어떤 종류의 사용자와 리소스가 있는지에 따라 크게 달라진다.

예를 들어, 간단한 블로그 시스템에서는 글 작성자만 자신의 글을 수정할 수 있게 하는 단순한 인가 로직을 사용할 수 있다. 반면, 복잡한 기업용 시스템에서는 조직 구조, 직급, 부서, 프로젝트 참여 여부 등 다양한 요소를 고려한 세밀한 인가 규칙을 정의해야 할 수 있다.

결국 인가는 해당 시스템을 어떻게 설계하고 구현하느냐에 따라 그 형태가 결정된다. 따라서 시스템 설계 단계에서 인증뿐만 아니라 인가에 대해서도 깊이 있는 고민과 설계가 필요하다.