1. Amazon Cognito 개요
🤔 Cognito가 뭔가요?
비유로 이해하기: Cognito는 앱의 회원 관리 시스템입니다.
- 직접 만들면: 회원가입, 로그인, 비밀번호 재설정, MFA, 소셜 로그인... 😰
- Cognito 사용: AWS가 다 해줌! 😊
Cognito의 두 가지 핵심 서비스
┌─────────────────────────────────────────────────────────────────┐
│ Amazon Cognito │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Cognito User Pools (CUP) │ │
│ │ │ │
│ │ "인증" (Authentication) = 누구인가? │ │
│ │ │ │
│ │ • 회원가입 / 로그인 │ │
│ │ • 비밀번호 재설정 │ │
│ │ • 소셜 로그인 (Google, Facebook...) │ │
│ │ • MFA (다중 인증) │ │
│ │ → JWT 토큰 반환 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Cognito Identity Pools │ │
│ │ (Federated Identity) │ │
│ │ │ │
│ │ "권한 부여" (Authorization) = 뭘 할 수 있는가? │ │
│ │ │ │
│ │ • AWS 자격 증명(Credentials) 발급 │ │
│ │ • 사용자가 직접 AWS 리소스에 접근 │ │
│ │ • S3, DynamoDB 등에 직접 접근 가능 │ │
│ │ → 임시 AWS Credentials 반환 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ CUP + Identity Pools = 완전한 인증 + 권한 부여 솔루션 │
│ │
└─────────────────────────────────────────────────────────────────┘Cognito vs IAM
| 항목 | IAM | Cognito |
|---|---|---|
| 대상 | AWS 내부 사용자/서비스 | 앱 사용자 |
| 규모 | 수십~수백 명 | 수백만 명 |
| 사용자 유형 | 개발자, 관리자 | 일반 사용자, 모바일 사용자 |
| 인증 방식 | Access Key, MFA | 소셜 로그인, SAML, OIDC |
Cognito를 선택하는 키워드:
• "수백 명의 사용자"
• "모바일 앱 사용자"
• "소셜 로그인"
• "SAML 인증"
• "외부 사용자"2. Cognito User Pools (CUP)
🤔 User Pool이 뭔가요?
비유로 이해하기: 서버리스 회원 DB + 인증 시스템입니다.
- 회원 정보 저장 (이메일, 비밀번호, 속성...)
- 로그인 처리 (비밀번호 확인, MFA...)
- 토큰 발급 (JWT)
User Pool 기능
┌─────────────────────────────────────────────────────────────────┐
│ Cognito User Pools 기능 │
│ │
│ ✅ 기본 인증 │
│ ├─ 사용자명 / 이메일 로그인 │
│ ├─ 비밀번호 정책 │
│ └─ 비밀번호 재설정 │
│ │
│ ✅ 검증 │
│ ├─ 이메일 인증 │
│ └─ 전화번호 인증 (SMS) │
│ │
│ ✅ 보안 │
│ ├─ MFA (다중 인증) │
│ ├─ 비밀번호 유출 감지 (다른 사이트에서 유출된 비밀번호 차단) │
│ └─ Adaptive Authentication (위험 기반 인증) │
│ │
│ ✅ 소셜 로그인 (Federation) │
│ ├─ Google │
│ ├─ Facebook │
│ ├─ Apple │
│ ├─ Amazon │
│ └─ SAML / OIDC (기업 IdP) │
│ │
│ → 로그인 성공 시 JWT 토큰 반환! │
│ │
└─────────────────────────────────────────────────────────────────┘User Pool 동작 흐름
┌─────────────────────────────────────────────────────────────────┐
│ CUP 인증 흐름 │
│ │
│ 1. 사용자 로그인 요청 │
│ ┌─────────────────┐ │
│ │ Web/Mobile App │ │
│ │ "Login" 버튼 │ │
│ └────────┬────────┘ │
│ │ 이메일: user@example.com │
│ │ 비밀번호: ******** │
│ ↓ │
│ │
│ 2. Cognito User Pool에서 인증 │
│ ┌─────────────────────────────────────────────┐ │
│ │ Cognito User Pool │ │
│ │ │ │
│ │ ┌────────────────────────────────────────┐ │ │
│ │ │ User Database │ │ │
│ │ │ • user@example.com │ │ │
│ │ │ • 비밀번호 해시 │ │ │
│ │ │ • MFA 설정 │ │ │
│ │ └────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 1) 비밀번호 확인 ✓ │ │
│ │ 2) MFA 확인 (필요시) ✓ │ │
│ │ 3) JWT 토큰 생성 │ │
│ └──────────────────────┬──────────────────────┘ │
│ │ │
│ ↓ │
│ │
│ 3. JWT 토큰 반환 │
│ ┌─────────────────────────────────────────────┐ │
│ │ { │ │
│ │ "id_token": "eyJhbGciOi...", │ │
│ │ "access_token": "eyJhbGciOi...", │ │
│ │ "refresh_token": "eyJhbGciOi..." │ │
│ │ } │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘CUP과 API Gateway 연동
┌─────────────────────────────────────────────────────────────────┐
│ CUP + API Gateway │
│ │
│ 1. 사용자가 CUP에서 로그인 → JWT 토큰 받음 │
│ │
│ 2. API 요청 시 JWT 토큰 포함 │
│ GET /api/data │
│ Authorization: Bearer eyJhbGciOi... │
│ │
│ 3. API Gateway가 토큰 검증 │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Client │───→│ API Gateway │ │
│ │ (JWT 토큰) │ │ (토큰 검증) │ │
│ └─────────────────┘ └────────┬────────┘ │
│ │ │
│ ↓ 검증 성공 │
│ ┌─────────────────┐ │
│ │ Lambda Backend │ │
│ └─────────────────┘ │
│ │
│ ⚠️ API Gateway에서 직접 Cognito 토큰 검증 가능! │
│ │
└─────────────────────────────────────────────────────────────────┘CUP과 ALB 연동
┌─────────────────────────────────────────────────────────────────┐
│ CUP + Application Load Balancer │
│ │
│ 1. 사용자가 ALB로 요청 │
│ GET /app │
│ │
│ 2. ALB가 Cognito로 리다이렉트 (인증 필요 시) │
│ │
│ 3. 사용자가 Cognito에서 로그인 │
│ │
│ 4. ALB가 토큰 검증 후 Backend로 전달 │
│ │
│ ┌──────┐ ┌───────────────┐ ┌──────────┐ │
│ │ User │───→│ ALB │───→│ ECS/EC2 │ │
│ └──────┘ │ authenticate- │ │ Backend │ │
│ ↑ │ cognito │ └──────────┘ │
│ │ └───────┬───────┘ │
│ │ │ │
│ │ ↓ │
│ │ ┌───────────────┐ │
│ └──────│ Cognito User │ │
│ 로그인 UI │ Pool │ │
│ └───────────────┘ │
│ │
│ ⚠️ HTTPS 리스너 필수! │
│ ⚠️ 인증 액션: authenticate-cognito 또는 authenticate-oidc │
│ │
└─────────────────────────────────────────────────────────────────┘3. CUP - Lambda Triggers
🤔 Lambda Trigger가 뭔가요?
비유로 이해하기: 인증 과정의 이벤트 훅입니다.
- "로그인 전에 추가 검증하고 싶어" → Pre Authentication Trigger
- "회원가입 후 환영 이메일 보내고 싶어" → Post Confirmation Trigger
Lambda Trigger 종류
| 트리거 | 시점 | 용도 |
|---|---|---|
| Pre Sign-up | 회원가입 전 | 가입 허용/거부 검증 |
| Post Confirmation | 가입 완료 후 | 환영 이메일, 로그 기록 |
| Pre Authentication | 로그인 전 | 로그인 허용/거부 검증 |
| Post Authentication | 로그인 후 | 로그 기록, 분석 |
| Pre Token Generation | 토큰 생성 전 | 토큰에 클레임 추가/수정 |
| Custom Message | 메시지 전송 전 | 메시지 커스터마이징 |
| Migrate User | 사용자 마이그레이션 | 기존 DB에서 사용자 이전 |
Lambda Trigger 예시
┌─────────────────────────────────────────────────────────────────┐
│ Lambda Trigger 흐름 │
│ │
│ 회원가입 흐름: │
│ │
│ [사용자 가입 요청] │
│ │ │
│ ↓ │
│ [Pre Sign-up Lambda] ← 이메일 도메인 검증 │
│ │ "@company.com만 허용!" │
│ ↓ 허용 │
│ [Cognito 가입 처리] │
│ │ │
│ ↓ │
│ [Post Confirmation Lambda] ← 환영 이메일 전송 │
│ │ DB에 사용자 기록 │
│ ↓ │
│ [가입 완료!] │
│ │
└─────────────────────────────────────────────────────────────────┘Pre Sign-up Lambda 예시
// Lambda: Pre Sign-up (회사 이메일만 허용)
exports.handler = async event => {
const email = event.request.userAttributes.email;
// 회사 이메일만 허용
if (!email.endsWith("@company.com")) {
throw new Error("회사 이메일만 가입 가능합니다.");
}
// 자동 이메일 확인 (선택)
event.response.autoConfirmUser = true;
event.response.autoVerifyEmail = true;
return event;
};4. CUP - Hosted UI & Custom Domain
🤔 Hosted UI가 뭔가요?
비유로 이해하기: Cognito가 제공하는 기본 로그인 화면입니다.
- 직접 로그인 UI 만들 필요 없음!
- 소셜 로그인 버튼도 자동으로 추가됨
Hosted UI 특징
┌─────────────────────────────────────────────────────────────────┐
│ Cognito Hosted UI │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 로그인 │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ [Your Logo Here] │ │ │
│ │ │ │ │ │
│ │ │ 이메일: [____________________] │ │ │
│ │ │ 비밀번호: [____________________] │ │ │
│ │ │ │ │ │
│ │ │ [로그인] │ │ │
│ │ │ │ │ │
│ │ │ ───────── 또는 ───────── │ │ │
│ │ │ │ │ │
│ │ │ [G Google로 로그인] │ │ │
│ │ │ [f Facebook으로 로그인] │ │ │
│ │ │ │ │ │
│ │ │ 계정이 없으신가요? [회원가입] │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 커스터마이징: │
│ ✅ 로고 변경 │
│ ✅ CSS 커스터마이징 │
│ ✅ 소셜 IdP 버튼 추가/제거 │
│ │
└─────────────────────────────────────────────────────────────────┘Custom Domain 설정
기본 도메인:
https://your-domain-prefix.auth.ap-northeast-2.amazoncognito.com
커스텀 도메인:
https://auth.yourcompany.com
⚠️ 커스텀 도메인 사용 시:
• ACM 인증서 필요 (반드시 us-east-1에서 생성!)
• App Integration 섹션에서 설정5. CUP - Adaptive Authentication
🤔 Adaptive Authentication이 뭔가요?
비유로 이해하기: 위험 감지 보안 시스템입니다.
- 평소와 다른 로그인 패턴 감지
- 위험도에 따라 MFA 요구
동작 방식
┌─────────────────────────────────────────────────────────────────┐
│ Adaptive Authentication │
│ │
│ 평소 로그인 (위험도: 낮음) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 장소: 서울 │ │
│ │ 디바이스: 평소 사용하는 노트북 │ │
│ │ IP: 회사 IP │ │
│ │ 시간: 평일 오전 9시 │ │
│ │ │ │
│ │ → 비밀번호만으로 로그인 OK! │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 의심스러운 로그인 (위험도: 높음) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 장소: 해외 (평소와 다름!) │ │
│ │ 디바이스: 새로운 기기 (처음 보는 기기!) │ │
│ │ IP: 알려지지 않은 IP │ │
│ │ 시간: 새벽 3시 (비정상 시간!) │ │
│ │ │ │
│ │ → MFA 추가 요구! 또는 차단! │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 위험 요소: │
│ • 새로운 디바이스 │
│ • 새로운 위치/IP │
│ • 유출된 비밀번호 사용 시도 │
│ • 비정상적인 시간대 │
│ │
│ → CloudWatch Logs에 로그인 시도, 위험 점수 기록 │
│ │
└─────────────────────────────────────────────────────────────────┘6. JWT (JSON Web Token)
🤔 JWT가 뭔가요?
비유로 이해하기: 디지털 신분증입니다.
- 사진, 이름, 주소가 적힌 신분증
- 위조 방지 홀로그램 (서명)
JWT 구조
┌─────────────────────────────────────────────────────────────────┐
│ JWT 구조 │
│ │
│ eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. │
│ eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0. │
│ SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c │
│ ─────────────────┬───────────────────────┬────────────────────│
│ │ │ │ │
│ ↓ ↓ ↓ │
│ Header Payload Signature │
│ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ { │ │ { │ │ │ │
│ │ "alg": │ │ "sub": "uuid", │ │ Header + │ │
│ │ "RS256", │ │ "email": "...",│ │ Payload + │ │
│ │ "typ": │ │ "name": "...", │ │ Secret Key │ │
│ │ "JWT" │ │ "exp": 123456 │ │ → 암호화 │ │
│ │ } │ │ } │ │ │ │
│ └─────────────┘ └─────────────────┘ └─────────────────┘ │
│ 알고리즘 정보 사용자 정보 위조 방지 서명 │
│ │
└─────────────────────────────────────────────────────────────────┘JWT 검증
// JWT 검증 예시 (TypeScript)
import { CognitoJwtVerifier } from "aws-jwt-verify";
const verifier = CognitoJwtVerifier.create({
userPoolId: "ap-northeast-2_xxxxx",
tokenUse: "id", // "id" 또는 "access"
clientId: "xxxxxxxxxxxxx",
});
async function verifyToken(token: string) {
try {
const payload = await verifier.verify(token);
console.log("Token is valid. Payload:", payload);
// payload.sub = 사용자 ID
// payload.email = 이메일
// payload["custom:attribute"] = 커스텀 속성
return payload;
} catch (err) {
console.log("Token is invalid:", err);
throw err;
}
}7. Cognito Identity Pools
🤔 Identity Pool이 뭔가요?
비유로 이해하기: 임시 AWS 출입증 발급 창구입니다.
- User Pool = "당신이 누구인지 확인" (인증)
- Identity Pool = "AWS 리소스 접근 권한 발급" (권한 부여)
Identity Pool 동작 흐름
┌─────────────────────────────────────────────────────────────────┐
│ Identity Pool 동작 │
│ │
│ 1. 사용자가 IdP에서 로그인 (Cognito User Pool, Google 등) │
│ ┌─────────────────┐ │
│ │ Mobile App │ │
│ └────────┬────────┘ │
│ │ 로그인 │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Identity Provider (IdP) │ │
│ │ • Cognito User Pool │ │
│ │ • Google / Facebook / Apple │ │
│ │ • SAML / OIDC │ │
│ └─────────────────────────────────────────────┘ │
│ │ │
│ ↓ ID Token │
│ │
│ 2. Identity Pool에서 토큰을 AWS 자격 증명으로 교환 │
│ ┌─────────────────────────────────────────────┐ │
│ │ Cognito Identity Pool │ │
│ │ │ │
│ │ 1) ID Token 검증 │ │
│ │ 2) IAM Role 선택 (인증/비인증) │ │
│ │ 3) STS를 통해 임시 Credentials 발급 │ │
│ └─────────────────────────────────────────────┘ │
│ │ │
│ ↓ AWS Credentials (임시) │
│ • AccessKeyId │
│ • SecretAccessKey │
│ • SessionToken │
│ │
│ 3. AWS 리소스에 직접 접근! │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ S3 Bucket │ │ DynamoDB │ │
│ │ (Private) │ │ Table │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘CUP + Identity Pool 조합
┌─────────────────────────────────────────────────────────────────┐
│ CUP + Identity Pool │
│ │
│ ┌────────────┐ │
│ │ Mobile App │ │
│ └─────┬──────┘ │
│ │ │
│ │ 1. 로그인 (이메일/비밀번호) │
│ ↓ │
│ ┌─────────────────────┐ │
│ │ Cognito User Pool │ ← 인증 담당 │
│ │ (사용자 DB) │ │
│ └──────────┬──────────┘ │
│ │ │
│ │ 2. JWT Token │
│ ↓ │
│ ┌─────────────────────┐ │
│ │ Cognito Identity │ ← 권한 부여 담당 │
│ │ Pool │ │
│ └──────────┬──────────┘ │
│ │ │
│ │ 3. AWS Credentials (임시) │
│ ↓ │
│ ┌──────────────────────────────────────────┐ │
│ │ AWS 리소스 직접 접근! │ │
│ │ ┌────────┐ ┌────────────┐ ┌────────┐ │ │
│ │ │ S3 │ │ DynamoDB │ │ Lambda │ │ │
│ │ └────────┘ └────────────┘ └────────┘ │ │
│ └──────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘지원하는 Identity Provider
| Provider | 설명 |
|---|---|
| Cognito User Pool | 자체 사용자 DB |
| Google 계정 로그인 | |
| Facebook 계정 로그인 | |
| Apple | Apple ID 로그인 |
| Amazon | Amazon 계정 로그인 |
| SAML | 기업 IdP (Okta, AD FS...) |
| OIDC | OpenID Connect 호환 IdP |
| Guest (비인증) | 로그인 없이 제한된 접근 |
8. Identity Pool - IAM Roles
🤔 어떤 권한을 부여하나요?
인증된 사용자 vs 게스트 사용자
┌─────────────────────────────────────────────────────────────────┐
│ Identity Pool IAM Roles │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Authenticated Role (인증된 사용자) │ │
│ │ │ │
│ │ { │ │
│ │ "Effect": "Allow", │ │
│ │ "Action": [ │ │
│ │ "s3:GetObject", │ │
│ │ "s3:PutObject", │ │
│ │ "dynamodb:GetItem", │ │
│ │ "dynamodb:PutItem" │ │
│ │ ], │ │
│ │ "Resource": "*" │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Unauthenticated Role (게스트 사용자) │ │
│ │ │ │
│ │ { │ │
│ │ "Effect": "Allow", │ │
│ │ "Action": [ │ │
│ │ "s3:GetObject" ← 읽기만 허용 (제한된 권한) │ │
│ │ ], │ │
│ │ "Resource": "arn:aws:s3:::public-bucket/*" │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘Policy Variables (사용자별 접근 제어)
// S3: 사용자별 폴더만 접근 허용
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": ["arn:aws:s3:::my-bucket/${cognito-identity.amazonaws.com:sub}/*"]
}
]
}${cognito-identity.amazonaws.com:sub} = 사용자의 Identity ID
결과:
• User A (ID: abc123) → s3://my-bucket/abc123/* 접근 가능
• User B (ID: xyz789) → s3://my-bucket/xyz789/* 접근 가능
• 다른 사용자 폴더 접근 불가!DynamoDB Policy Variable 예시
// DynamoDB: 자신의 아이템만 접근 허용
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
}
}
}
]
}9. CUP vs Identity Pools 비교
한눈에 비교
| 항목 | User Pools (CUP) | Identity Pools |
|---|---|---|
| 목적 | 인증 (Authentication) | 권한 부여 (Authorization) |
| 기능 | 사용자 DB, 로그인 | AWS 자격 증명 발급 |
| 반환 | JWT 토큰 | AWS Credentials |
| 사용처 | API Gateway, ALB | 직접 AWS 접근 |
| 게스트 | ❌ | ✅ (비인증 접근 가능) |
| 소셜 로그인 | ✅ | ✅ |
| SAML/OIDC | ✅ | ✅ |
언제 뭘 써야 하나요?
┌─────────────────────────────────────────────────────────────────┐
│ 선택 가이드 │
│ │
│ Q1. 로그인 기능만 필요한가요? (API Gateway/ALB 연동) │
│ └─ Yes → Cognito User Pools만 │
│ │
│ Q2. 클라이언트에서 S3/DynamoDB에 직접 접근해야 하나요? │
│ └─ Yes → Cognito User Pools + Identity Pools │
│ │
│ Q3. 로그인 없이 게스트 접근이 필요한가요? │
│ └─ Yes → Identity Pools (Unauthenticated Role) │
│ │
│ 가장 일반적인 패턴: │
│ CUP (인증) + Identity Pools (AWS 접근) + API Gateway (백엔드) │
│ │
└─────────────────────────────────────────────────────────────────┘핵심 요약
Cognito 두 가지 서비스
| 서비스 | 역할 | 반환 |
|---|---|---|
| User Pools | 인증 (누구인가?) | JWT 토큰 |
| Identity Pools | 권한 부여 (뭘 할 수 있나?) | AWS Credentials |
User Pools 통합
| 서비스 | 연동 방법 |
|---|---|
| API Gateway | Cognito Authorizer |
| ALB | authenticate-cognito 액션 |
Identity Pools 특징
| 특징 | 설명 |
|---|---|
| Guest 접근 | 비인증 사용자 허용 가능 |
| Policy Variables | 사용자별 리소스 격리 |
| STS | 임시 자격 증명 발급 |