티스토리 뷰

카테고리 없음

인증/인가 서비스

불끈 2025. 5. 1. 20:58

 

1. 서비스 개요 및 목적

이 인증/인가 서버는 다양한 내부 서비스들의 사용자 인증과 권한 관리를 전담하는 **중앙 인증 서비스(Central Authentication Service)**입니다. 각 서비스마다 인증 로직을 중복 구현하는 대신, 이 서버를 통해 통합된 인증 및 인가 처리를 수행함으로써 다음과 같은 목적을 달성합니다:

  • 인증 로직의 중앙 집중화: 모든 서비스는 공통 인증 서버를 통해 로그인, 회원가입, 토큰 갱신 등의 기능을 위임받습니다.
  • 멀티테넌시 지원: 각기 다른 서비스를 '테넌트'로 분리하여, 독립적인 사용자 관리 및 인증 체계를 운영합니다.
  • 보안 표준화: JWT 기반 토큰 발급, OAuth 로그인, 역할 기반 접근 제어(RBAC)를 통해 일관된 보안 정책을 제공합니다.
  • 확장성 있는 인증 인프라: 다양한 인증 전략(예: 이메일, 소셜 로그인, MFA 등) 및 클라이언트 애플리케이션과의 유연한 연동을 고려한 구조로 설계됩니다.

 

 

 

2. 주요 기능 정의 (도메인 분리)

1️⃣ 인증 도메인 (Auth Domain)

사용자의 자격 증명을 검증하고, 토큰을 발급/관리하는 영역

  • 로그인(Login): 사용자 자격 증명을 확인하고 JWT 토큰 발급
  • 토큰 갱신(Refresh Token): 리프레시 토큰을 통해 새로운 액세스 토큰 발급
  • 로그아웃(Logout): 서버에서 리프레시 토큰 폐기 또는 블랙리스트 처리
  • OAuth 로그인 처리: 외부 OAuth 공급자와 연동 (Google, GitHub 등)
  • 권한 확인(RBAC): 사용자 역할(Role) 확인 및 접근 권한 검증

 

2️⃣ 회원 도메인 (User Domain)

사용자 정보를 생성·조회·수정·삭제하는 계정 관리 영역

  • 회원 생성 (Sign Up): 이메일/비밀번호/이름 등의 정보를 등록
  • 회원 조회 (Get User): 사용자 ID 또는 토큰 기반으로 회원 정보 반환
  • 회원 정보 수정: 이메일, 비밀번호, 프로필 등의 정보 변경
  • 회원 탈퇴: 사용자 계정 삭제 (soft-delete 또는 비활성화 처리 가능)
  • 비밀번호 초기화 요청 및 처리: 이메일 기반의 패스워드 재설정
  • 이메일 인증 처리: 계정 유효성 검증 (선택 사항)
  • ✅ 이 도메인은 일반적으로 users 또는 account API 경로 하위로 분리됨

 


도메인 분리의 장점

  • 유지보수성 향상: 사용자 정보와 인증 로직을 독립적으로 관리 가능
  • 보안 강화: 인증 로직만 독립 배포 및 보안 정책 적용 가능
  • 서비스 유연성: 회원 시스템은 내부/외부 시스템과 공유할 수 있음
  • 다양한 인증 정책 대응: 이메일 기반, 소셜 로그인, OTP 등 인증 방식 다양화 가능

 

 

 

3. 인증 도메인

1️⃣ 로그인 (Login)

사용자 요청: 클라이언트 -> 인증 도메인
클라이언트는 email, password와 함께 X-Tenant-ID 헤더를 포함하여 /auth/login 엔드포인트에 POST 요청.

POST /auth/login
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "email": "user@example.com",
  "password": "plaintext_password"
}

 

 

자격 검증: 인증 도메인 -> 회원 도메인
인증 서버는 X-Tenant-ID로 올바른 테넌트를 식별하고, 해당 테넌트의 회원도메인으로 이메일/비밀번호를 검증 요청

POST /users/validate-password
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "email": "user@example.com",
  "password": "plaintext_password"
}
{
  "valid": true, 
  "userId": "user-uuid",
  "status": "ACTIVE"
}

 

  • 비밀번호 검증 요청은 반드시 내부 서비스 간 호출이므로, 적절한 인증 및 권한 부여 메커니즘을 통해 접근을 제한해야 합니다.
  • validate-password API는 클라이언트와 외부에 노출되지 않으며, 인증 도메인에서만 호출 가능하도록 처리해야 합니다.

 

토큰 발급:

  • accessToken (JWT): 짧은 유효기간 (예: 15분)
  • refreshToken (UUID 또는 JWT): 긴 유효기간 (예: 14일)
  • refreshToken은 DB 또는 Redis에 저장됨 (key = userId + tenantId)
{
  "accessToken": "eyJhbGciOiJIUzI1...",
  "refreshToken": "8a12e3cc-..."
}

 

응답 반환:
클라이언트는 accessToken, refreshToken을 저장하고 이후 요청 시 사용.


2️⃣ 인증 요청 (API 요청 시 accessToken 사용)

사용자 요청:
클라이언트는 유효한 accessToken과 함께 API 요청을 보냅니다.
이때 Authorization 헤더에 Bearer {accessToken}을 포함하고, X-Tenant-ID를 명시하여 요청합니다.

GET /api/resource
Headers:
  Authorization: Bearer {accessToken}
  X-Tenant-ID: tenant_123

 

 

인증 도메인에서 accessToken 검증:

인증 도메인은 다음을 수행합니다:

  • accessToken 검증:
    • JWT 서명 확인
    • 만료 시간 검사
    • issuer와 audience 확인 (JWT 내부의 claims)
  • 검증이 실패할 경우 401 Unauthorized 오류 반환.

검증 성공 시:

  • JWT 내부에서 sub, tenantId, role 등의 정보 추출
  • tenantId와 X-Tenant-ID 비교 → 일치 여부 확인
{
  "sub": "user-uuid",
  "tenantId": "tenant_123",
  "role": "USER",
  "exp": "2025-05-01T12:30:00Z"
}

 

권한 확인 (Role-Based Access Control):

인증된 사용자에 대한 권한 확인:

  • 요청된 리소스에 대해 해당 사용자가 권한이 있는지 확인 (RBAC)
  • 예를 들어, role 값이 "USER"인 사용자는 관리자 페이지에 접근할 수 없도록 제한할 수 있음

정상 응답 또는 403/401 오류 반환

정상 응답:

  • 권한이 확인되면, 요청된 리소스를 반환합니다.
{
  "data": "resource data here"
}

 

권한 오류 (403 Forbidden):

  • 사용자가 해당 리소스에 접근할 권한이 없을 경우 403 Forbidden 오류 반환.

 

🔒 보안 및 고려사항

  • JWT 토큰 유효성 검증: 클라이언트에서 보내는 JWT가 유효한지 검증해야 합니다. 만약 유효하지 않으면 401 Unauthorized 응답을 반환합니다.
  • Tenant 격리: X-Tenant-ID가 accessToken의 tenantId와 일치해야 하며, 그렇지 않으면 403 Forbidden을 반환합니다.
  • 권한 검사: 각 리소스에 대한 접근 권한을 RBAC 기반으로 검증합니다.

 


3️⃣ 토큰 갱신 (accessToken 만료 시 refreshToken 사용)

요청:
클라이언트는 만료된 accessToken을 가지고 API 요청을 보냅니다. 이때, accessToken이 만료된 상태이므로 refreshToken을 사용해 토큰을 갱신합니다.

POST /auth/token/refresh
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "refreshToken": "8a12e3cc-..."
}

 

검증:

인증 도메인은 refreshToken을 검증합니다:

  • 유효성 검증:
    • DB 또는 Redis에서 해당 refreshToken을 조회하여 검증
    • 만약 refreshToken이 유효하지 않거나, 만료되었거나, 블랙리스트에 있다면 401 Unauthorized 오류 반환
  • refreshToken이 유효하면 **userId와 tenantId**를 추출합니다.

 

새 accessToken 발급:

검증이 완료되면 인증 도메인은 새로운 accessToken을 발급합니다:

  • 기존의 userId, tenantId, role 등을 기반으로 새로운 JWT accessToken 발급
  • 새로 발급된 accessToken은 짧은 유효 기간을 가집니다 (예: 15분)
  • 클라이언트는 응답 받은 accessToken을 저장하고, 추후 API 요청 시 사용합니다. 필요시 refreshToken을 갱신하여 사용합니다.
{
  "accessToken": "eyJhbGciOiJIUzI1...",
  "refreshToken": "8a12e3cc-..."
}

 

🔒 보안 및 고려사항

  • refreshToken 보안: refreshToken은 클라이언트 측에서 안전하게 보관되어야 하며, httpOnly 쿠키로 저장하는 방식이 좋습니다.
  • refreshToken 유효성 검증: 서버에서 refreshToken을 검증할 때, 만약 여러 날을 거쳐서 요청이 이루어질 수 있으므로 refreshToken의 만료 시간을 엄격히 관리해야 합니다.
  • 이중 갱신 전략: 보안 상의 이유로, 새로운 refreshToken을 갱신하는 전략을 사용할 수도 있습니다. 이때 기존 refreshToken은 더 이상 유효하지 않도록 설정할 수 있습니다.

4️⃣ 로그아웃

요청:
클라이언트는 로그아웃 요청을 refreshToken과 함께 보내면서, 자신이 로그아웃하려는 테넌트를 X-Tenant-ID 헤더에 포함시킵니다.

POST /auth/logout
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "refreshToken": "8a12e3cc-..."
}

 

처리:

인증 도메인은 refreshToken을 확인합니다:

  • refreshToken 유효성 검사:
    • DB 또는 Redis에서 해당 refreshToken을 조회하여 검증합니다.
    • 만약 refreshToken이 만료되었거나, 유효하지 않거나, 이미 로그아웃된 경우에는 401 Unauthorized 오류를 반환할 수 있습니다.

 

refreshToken 무효화:

refreshToken이 유효한 경우, 인증 도메인은 이를 무효화합니다:

  • DB 또는 Redis에서 삭제하거나 블랙리스트 처리(refreshToken의 유효성을 차단하는 방식)
  • 이 작업은 클라이언트에서 사용한 refreshToken을 무효화하여, 이후 해당 refreshToken으로는 토큰을 갱신할 수 없도록 합니다.

응답 반환

클라이언트에게 로그아웃 성공 메시지를 반환합니다.

{
  "message": "Logout successful"
}

 

 

🔒 보안 및 고려사항

  • refreshToken 무효화: DB 또는 Redis에서 refreshToken을 삭제하거나 블랙리스트에 추가하는 방식으로 로그아웃 시 무효화가 되어야 합니다. 이렇게 해야 악의적인 사용자가 동일한 refreshToken으로 다시 갱신을 시도할 수 없습니다.
  • 클라이언트 측 처리: 클라이언트는 로그아웃 시 localStorage, sessionStorage, 쿠키 등에 저장된 accessToken과 refreshToken을 반드시 삭제해야 합니다.
  • 세션 관리: 만약 refreshToken을 블랙리스트로 관리한다면, 서버에서 주기적으로 블랙리스트를 정리하는 작업도 필요할 수 있습니다.

 

 

4. 회원 도메인

1️⃣ 회원 등록 (새로운 사용자 가입)

클라이언트 → 회원 도메인

POST /users
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "email": "newuser@example.com",
  "password": "plaintext_password",
  "role": "USER"
}

 

  • 새로운 사용자가 가입할 때 emailpassword를 전달하여 계정을 생성합니다.
  • 비밀번호는 반드시 해시화하여 저장합니다.
{
  "message": "User created successfully",
  "userId": "new-user-uuid"
}

 

 

2️⃣ 회원 정보 수정 (비밀번호 변경, 이메일 변경 등)

클라이언트 → 회원 도메인

PUT /users/{userId}
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "email": "updateduser@example.com",
  "password": "newplaintext_password",
  "role": "USER"
}

 

  • 기존 사용자의 정보를 업데이트할 때 사용됩니다.
  • 비밀번호 변경 시, 새 비밀번호는 해시화하여 저장합니다.
  •  
{
  "message": "User updated successfully"
}

 

 

 

3️⃣ 회원 상태 변경 (활성화/비활성화)

클라이언트 → 회원 도메인

PATCH /users/{userId}/status
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "status": "INACTIVE"
}

 

  • 사용자의 상태를 활성화/비활성화 할 때 사용됩니다.
  • 예를 들어, 사용자가 휴면 상태로 전환되거나 관리자에 의해 계정이 비활성화 될 수 있습니다.

 

{
  "message": "User status updated successfully"
}

 

 

4️⃣ 회원 삭제 (사용자 탈퇴)

클라이언트 → 회원 도메인

DELETE /users/{userId}
Headers:
  X-Tenant-ID: tenant_123
{
  "message": "User deleted successfully"
}

 

5️⃣ 회원 정보 조회 (email을 기반으로 사용자 조회)

클라이언트 → 회원 도메인

GET /users/by-email
Headers:
  X-Tenant-ID: tenant_123
Query Parameters:
  email: "user@example.com"

 

  • 클라이언트는 이메일을 기반으로 회원 정보를 조회합니다.
  • 이 API는 인증된 사용자만 접근할 수 있으며, 주로 인증 도메인에서 사용됩니다.
{
  "id": "user-uuid",
  "email": "user@example.com",
  "status": "ACTIVE",
  "role": "USER",
  "createdAt": "2023-01-01T12:00:00Z"
}

 

6️⃣ 회원 비밀번호 검증 (인증 도메인에서 호출)

 

인증 도메인 → 회원 도메인

POST /users/validate-password
Headers:
  X-Tenant-ID: tenant_123
Body:
{
  "email": "user@example.com",
  "password": "plaintext_password"
}

 

 

  • 인증 도메인에서 emailpassword를 전달하여 비밀번호가 맞는지 확인합니다.
  • **password**는 비밀번호 해시화 후 비교하는 방식으로 구현됩니다.
{
  "valid": true,
  "userId": "user-uuid",
  "status": "ACTIVE"
}
  • valid가 false일 경우 인증 실패 처리

 

 

 

🔒 보안 고려사항

  • 회원 정보 조회비밀번호 검증 API는 반드시 인증된 사용자만 접근할 수 있어야 하므로, 인증 도메인에서 사용하는 **accessToken**이나 API Gateway 인증을 반드시 거쳐야 합니다.
  • 비밀번호 해시화는 반드시 bcrypt 등 안전한 해시 알고리즘을 사용해야 합니다.
  • 민감한 정보비밀번호는 절대로 평문으로 저장하거나 반환하지 않도록 해야 합니다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함