서버리스 앱에서의 인증

이전 섹션에서 서버리스 REST API를 만들고 배포했습니다. 하지만 몇 가지 빠진 부분이 있습니다.

  1. 보안이 적용되지 않았습니다.
  2. 특정 사용자와 연결되지 않았습니다.

이 두 문제는 서로 연결되어 있습니다. 우리는 사용자가 노트 앱에 가입할 수 있도록 하고, 인증된 사용자만 액세스할 수 있게 해야 합니다.

이번 섹션에서는 바로 이 작업을 수행하는 방법을 배울 것입니다. AWS 환경에서 인증(및 접근 제어)이 어떻게 작동하는지 이해하는 것부터 시작하겠습니다.

퍼블릭 API 아키텍처

참고로, 현재까지의 구조는 다음과 같습니다.

서버리스 퍼블릭 API 아키텍처

사용자들이 서버리스 API에 요청을 보내면, API Gateway 엔드포인트로 요청이 전달됩니다. 요청한 엔드포인트에 따라 해당 요청은 적절한 Lambda 함수로 전달됩니다.

접근 제어 측면에서, API Gateway 엔드포인트는 infra/api.ts 파일의 라우트에 정의된 Lambda 함수를 호출할 수 있습니다. 그리고 Lambda 함수는 DynamoDB 테이블에 연결할 수 있습니다.

link: [table],

파일 업로드의 경우, 사용자들은 파일을 직접 S3 버킷에 업로드합니다. 프론트엔드 React 앱이 파일을 업로드하는 방법은 가이드 후반부에서 다룰 예정이지만, 이 섹션에서는 S3 버킷에 대한 접근을 안전하게 보호해야 합니다.

인증된 API 아키텍처

사용자가 노트 앱에 가입할 수 있도록 하고, 인프라를 보호하기 위해 다음과 같은 아키텍처로 전환할 예정입니다.

서버리스 인증 API 아키텍처

여기에는 조금 더 복잡한 내용이 있습니다. 각 부분을 자세히 살펴보겠습니다.

시작하기 전에 몇 가지 간단한 설명을 드리겠습니다:

  1. 이 다이어그램의 서버리스 API 부분은 이전에 살펴본 것과 정확히 동일합니다. 다이어그램을 간단히 표현하기 위해 축약된 형태입니다.

  2. 여기서 사용자는 우리의 React 앱 또는 _클라이언트_를 효과적으로 나타냅니다.

Cognito 사용자 풀

사용자의 회원가입 및 로그인 기능을 관리하기 위해 Amazon Cognito 사용자 풀이라는 AWS 서비스를 사용할 예정입니다. 이 서비스는 사용자의 로그인 정보를 저장하고, React 앱에서 사용자 세션을 관리합니다.

Cognito Identity Pool

AWS 인프라에 대한 접근 제어를 관리하기 위해 Amazon Cognito Identity Pools라는 서비스를 사용합니다. 이 서비스는 이전에 인증된 사용자가 접근하려는 리소스에 대한 권한이 있는지 결정합니다. Identity Pool은 다양한 인증 프로바이더(예: Cognito User Pools, Facebook, Google 등)를 가질 수 있습니다. 우리의 경우, Identity Pool은 User Pool에 연결됩니다.

User Pool과 Identity Pool의 차이점이 조금 혼란스럽다면 걱정하지 마세요. 이를 도와줄 챕터가 있습니다 — Cognito User Pool vs Identity Pool

인증 역할(Auth Role)

우리의 Cognito Identity Pool에는 IAM 역할이라고 불리는 규칙 집합이 연결되어 있습니다. 이 규칙은 인증된 사용자가 접근할 수 있는 리소스를 나열합니다. 이러한 리소스는 ARN이라는 ID를 사용하여 나열됩니다.

IAM과 ARN을 더 잘 이해할 수 있도록 도와주는 몇 가지 챕터가 있습니다:

하지만 지금은 인증된 사용자들이 Identity Pool의 Auth Role을 사용하여 우리의 리소스와 상호작용합니다. 이를 통해 로그인한 사용자들이 우리의 노트 API에만 접근할 수 있고, AWS 계정의 다른 API에는 접근할 수 없도록 보장할 수 있습니다.

인증 흐름

위에서 설명한 요소들이 실제로 어떻게 동작하는지 살펴보겠습니다.

회원가입

사용자는 새로운 User Pool 계정을 생성하여 노트 앱에 가입합니다. 이메일과 비밀번호를 사용합니다. 이메일을 확인하기 위한 코드가 전송됩니다. 이 과정은 React 앱과 User Pool 간에 처리됩니다. 다른 인프라는 이 과정에 관여하지 않습니다.

로그인

가입한 사용자는 이제 이메일과 비밀번호를 사용해 로그인할 수 있습니다. 리액트 앱은 이 정보를 User Pool로 전송합니다. 정보가 유효하면 리액트에서 세션이 생성됩니다.

인증된 API 요청

API에 연결하려면 다음 단계를 따릅니다.

  1. React 클라이언트가 IAM 인증으로 보호된 API Gateway에 요청을 보냅니다.
  2. API Gateway는 Identity Pool을 통해 사용자가 User Pool로 인증되었는지 확인합니다.
  3. Auth Role을 사용해 해당 사용자가 이 API에 접근할 수 있는지 판단합니다.
  4. 모든 것이 정상적이라면 Lambda 함수가 호출되고, Identity Pool 사용자 ID가 전달됩니다.

S3 파일 업로드

우리의 React 클라이언트는 파일을 S3 버킷에 직접 업로드할 것입니다. API와 마찬가지로, Identity Pool을 통해 User Pool로 인증되었는지 확인합니다. 그리고 Auth Role이 S3 버킷에 파일을 업로드할 수 있는 권한이 있는지도 확인합니다.

대체 인증 방법

API를 보호하는 다른 방법들도 간단히 언급할 가치가 있습니다. 앞서 Identity Pool이 Facebook이나 Google을 인증 프로바이더로 사용할 수 있다고 말씀드렸습니다. 따라서 User Pool 대신 Facebook이나 Google을 사용할 수 있습니다. Facebook에 대해 특별히 다루는 추가 자료가 있습니다 — AWS Amplify를 사용한 Cognito와 Facebook 로그인

또한 User Pool을 API Gateway에 직접 연결할 수도 있습니다. 이 방법의 단점은 S3 버킷(또는 향후 다른 AWS 리소스)에 대한 접근 제어를 중앙에서 관리하기 어려울 수 있다는 점입니다.

마지막으로, 여러분이 직접 사용자와 인증을 관리할 수도 있습니다. 이 방법은 조금 더 복잡하며, 이 가이드에서는 다루지 않습니다. 나중에 이에 대해 더 자세히 다룰 수도 있습니다.

이제 서버리스 앱에서 사용자와 인증을 어떻게 처리할지에 대한 좋은 아이디어를 얻었으니, 앱에 인증 인프라를 추가해 보겠습니다.