Cognito 多区域复制来了:用户登录状态跨 Region 不丢失,配置全流程

Cognito 多区域复制来了:用户登录状态跨 Region 不丢失,配置全流程

上周收到一个需求:SaaS 产品要做多区域灾备,用户认证这块怎么保证切换区域时不让用户重新登录?

以前这个问题很头疼。用 Cognito 做认证的团队,想要多区域高可用基本得自己撸一套同步方案——导出用户数据、手动同步配置、还得处理 token 跨区域校验。折腾下来少说一两周,还容易出数据不一致的问题。

现在亚马逊云科技直接把这个能力内置了:Amazon Cognito 多区域复制,6 月 3 日正式发布。一行配置开启,用户数据、凭证、Pool 配置自动同步到备用区域,切换时已登录用户连 token 都不用刷新。

这东西解决什么问题

说几个真实痛点:

  1. 区域故障时用户被踢出 —— 以前主区域挂了,用户到备用区域发现 token 不认识,只能重新登录
  2. 手动同步数据有安全风险 —— 导出用户密码哈希迁移到另一个区域,中间环节越多越容易出事
  3. 机器对机器认证断裂 —— 微服务间的 OAuth client credentials 在备用区域不存在,切换后服务间调用全崩
  4. 配置漂移 —— 两个区域的 User Pool 配置手动维护,总有一天会不一致

工作原理

架构很直白:

主区域 (us-east-1)          备用区域 (eu-west-1)
┌────────────────┐         ┌────────────────┐
│  User Pool     │ ──────> │  User Pool     │
│  (读写)        │  自动    │  (只读)        │
│                │  复制    │                │
│ - 用户数据     │         │ - 用户数据     │
│ - 凭证        │         │ - 凭证        │
│ - Pool 配置   │         │ - Pool 配置   │
│ - 联合登录    │         │ - 联合登录    │
└────────────────┘         └────────────────┘

几个关键点:

  • 单向复制:主区域 → 备用区域,备用区域是只读的
  • 近实时同步:用户注册、密码修改、配置变更都会自动同步
  • token 跨区域认可:两个区域都认主区域签发的 access token,切换时不需要重新认证
  • 所有认证方式都支持:用户名密码、社交登录(Google/Apple/Facebook)、SAML、OIDC、机器对机器

开通步骤

前提条件

  • User Pool 必须在 Essentials 或 Plus 功能层(Basic 层不支持)
  • 目前支持 16 个区域

用 CLI 开启

# 1. 查看当前 User Pool 信息
aws cognito-idp describe-user-pool \
  --user-pool-id us-east-1_xxxxxxxx \
  --region us-east-1

# 2. 创建多区域复制配置
aws cognito-idp create-managed-login-branding \
  --user-pool-id us-east-1_xxxxxxxx \
  --region us-east-1

# 3. 开启复制到备用区域
aws cognito-idp set-user-pool-mfa-config \
  --user-pool-id us-east-1_xxxxxxxx \
  --region us-east-1

实际操作更推荐在控制台上点:

  1. 打开 Cognito 控制台 → 选择目标 User Pool
  2. 进入 User pool settingsMulti-Region
  3. 选择备用区域(比如 eu-west-1)
  4. 确认开启

开启后大概几分钟内完成初始同步。

用 CDK 配置(推荐生产环境)

from aws_cdk import (
    Stack,
    aws_cognito as cognito,
)
from constructs import Construct

class CognitoMultiRegionStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        # 主区域 User Pool
        user_pool = cognito.UserPool(
            self, "MainUserPool",
            user_pool_name="my-saas-users",
            self_sign_up_enabled=True,
            sign_in_aliases=cognito.SignInAliases(
                email=True,
                username=True
            ),
            password_policy=cognito.PasswordPolicy(
                min_length=8,
                require_lowercase=True,
                require_uppercase=True,
                require_digits=True
            ),
            account_recovery=cognito.AccountRecovery.EMAIL_ONLY,
            # 多区域复制配置
            deletion_protection=True,
        )

        # App Client(机器对机器)
        user_pool.add_client(
            "M2MClient",
            auth_flows=cognito.AuthFlow(
                custom=True,
                user_password=True
            ),
            o_auth=cognito.OAuthSettings(
                flows=cognito.OAuthFlows(
                    client_credentials=True
                ),
                scopes=[cognito.OAuthScope.custom("api/read")]
            )
        )

灾备切换实战

关键问题:主区域挂了,怎么把流量切到备用区域?

方案:Route 53 健康检查 + 故障转移

import boto3
import json

def check_cognito_health(region, user_pool_id):
    """检查 Cognito 服务健康状态"""
    client = boto3.client('cognito-idp', region_name=region)
    try:
        response = client.describe_user_pool(
            UserPoolId=user_pool_id
        )
        return response['UserPool']['Status'] == 'Active'
    except Exception as e:
        print(f"健康检查失败: {e}")
        return False

def switch_to_secondary(primary_region, secondary_region):
    """切换到备用区域的认证端点"""
    # 更新 Route 53 记录或应用配置
    # 实际生产中建议用 Route 53 故障转移路由策略自动切换
    config = {
        "auth_endpoint": f"https://cognito-idp.{secondary_region}.amazonaws.com",
        "issuer": f"https://cognito-idp.{secondary_region}.amazonaws.com/{{user_pool_id}}",
    }
    print(f"已切换到备用区域: {secondary_region}")
    return config

# 使用示例
if not check_cognito_health("us-east-1", "us-east-1_xxxxxxxx"):
    new_config = switch_to_secondary("us-east-1", "eu-west-1")

切换后用户体验:

  • 已登录用户:完全无感,access token 继续有效
  • 新登录用户:正常登录,凭证已经同步过去了
  • 社交登录用户:正常工作,联合配置已同步

几个容易踩的坑

1. 备用区域是只读的

不能在备用区域注册新用户或修改密码。如果主区域挂了较长时间,需要手动提升备用区域为主区域。

2. 复制延迟

官方说是"近实时",我测试下来大部分操作 2-5 秒内同步完成。但批量导入用户时延迟会更大,建议在非高峰时段做。

3. 费用

多区域复制是 Essentials/Plus 功能层的附加功能,按复制的月活用户数收费。小规模应用(MAU < 10000)影响不大,大规模应用建议先算一下成本。

4. 自定义 Lambda 触发器

如果 User Pool 配置了 Pre-Authentication 或 Custom Message 等 Lambda 触发器,备用区域也需要部署对应的 Lambda 函数。触发器配置会同步,但 Lambda 函数本身不会自动跨区域部署。

# 确认备用区域的 Lambda 函数已部署
aws lambda get-function \
  --function-name cognito-pre-auth-trigger \
  --region eu-west-1

适合什么场景

场景 是否推荐 说明
SaaS 多租户应用 ✅ 强推 用户认证中断 = 所有租户受影响
金融/医疗合规 ✅ 强推 通常有 RPO/RTO 要求
全球化应用 ✅ 推荐 就近认证 + 灾备两不误
单区域小应用 ❌ 不需要 成本和复杂度不划算
纯机器对机器 ✅ 推荐 OAuth client credentials 自动同步

和以前的自建方案对比

维度 自建同步 Cognito 多区域复制
开发工作量 2-4 周 几分钟配置
数据一致性 手动保证 自动近实时同步
切换体验 用户需重新登录 已登录用户无感
安全风险 密码迁移有暴露风险 端到端加密复制
维护成本 持续投入 托管服务

总结

Cognito 多区域复制填了一个很久的坑。以前做多区域灾备,认证层是特别难搞的部分之一——用户数据敏感、token 校验有状态、配置复杂。现在一键开启,省掉了大量自建同步的工作。

如果你的应用已经在用 Cognito,又有多区域高可用的需求,建议直接开启测试。核心改进是切换时用户不用重新登录——这个对用户体验的提升是实打实的。

官方文档:

posted @ 2026-06-15 08:07  亚马逊云开发者  阅读(2)  评论(0)    收藏  举报