示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载导读本指南以 kotlin/services/cognito 目录下的 AWS SDK for Kotlin 示例代码为蓝本系统讲解如何用 Kotlin 调用 Amazon Cognito 的两大核心服务Cognito Identity身份池与Cognito Identity Provider用户池。你将掌握身份池的创建、列举、删除与成员查询用户池的创建、描述、删除、用户管理与注册以及一套完整的注册 → 确认 → 登录 → 绑定 TOTP 多因素认证MFA端到端场景并学会如何在本地运行这些示例、用 JUnit 5 驱动真实 AWS 资源测试。概述Amazon Cognito 在 Kotlin 示例中的定位Amazon Cognito 是一项用户身份与数据同步服务帮助你在移动设备与 Web 应用之间安全地管理、同步用户的身份数据。在本仓库中Kotlin 示例将其拆分为两个职责互补的 APICognitoIdentityClient面向身份池identity pool用于为未经认证或通过第三方身份提供商认证的用户签发临时 AWS 凭证让客户端可以安全访问 S3、DynamoDB 等 AWS 资源。CognitoIdentityProviderClient面向用户池user pool提供完整的用户目录能力包括注册、登录、密码管理、属性配置与 MFA 等。两类客户端在 build.gradle.kts 中分别对应aws.sdk.kotlin:cognitoidentity与aws.sdk.kotlin:cognitoidentityprovider两个依赖统一由aws.sdk.kotlin:bom:1.5.63平台约束管理版本。环境准备与重要注意事项运行本目录示例前需要先按 AWS SDK for Kotlin 的官方指引完成开发环境配置包括设置凭证。示例全部使用CognitoIdentityClient.fromEnvironment { region us-east-1 }这种从环境读取凭证 显式指定区域的客户端构建方式。⚠️ 以下几点务必留意这些 Kotlin 示例会针对你凭证所对应的 AWS 账户与区域执行真实操作运行可能产生AWS 服务费用运行测试同样可能产生费用。部分示例属于破坏性操作例如deleteUserPool删除用户池、deleteIdentityPool删除身份池。操作前请务必小心建议使用独立的、仅用于测试的资源避免影响生产数据。建议遵循least privilege最小权限原则仅授予执行任务所需的最低权限。示例并未在全部 AWS 区域完成测试us-east-1之外请自行验证可用性。一、身份池操作CognitoIdentityClient 四个示例以下四个示例均使用CognitoIdentityClient源码位于 src/main/kotlin/com/kotlin/cognito 包com.kotlin.cognito下。1. 创建身份池createIdentityPool文件CreateIdentityPool.kt命令行运行方式identityPoolName要创建的身份池名称。核心实现如下suspend fun createIdPool(identityPoolName: String?): String? { val request CreateIdentityPoolRequest { this.allowUnauthenticatedIdentities false this.identityPoolName identityPoolName } CognitoIdentityClient.fromEnvironment { region us-east-1 }.use { cognitoIdentityClient - val response cognitoIdentityClient.createIdentityPool(request) return response.identityPoolId } }关键参数identityPoolName身份池名称作为池的唯一业务标识。allowUnauthenticatedIdentities是否允许未认证身份访问池。示例中设为false即要求所有访问者都经过认证如果你的场景需要支持匿名访客例如公开读区的移动 App可设为true。返回值identityPoolId形如us-east-1:xxxx-xxxx-xxxx后续删除身份池、列举身份时都要用到。2. 删除身份池deleteIdentityPool文件DeleteIdentityPool.kt命令行运行方式identityPoolName——注意这里传入的实际是身份池 ID即上一步返回的identityPoolId。suspend fun deleteIdPool(identityPoold: String?) { val request DeleteIdentityPoolRequest { this.identityPoolId identityPoold } CognitoIdentityClient.fromEnvironment { region us-east-1 }.use { cognitoIdclient - cognitoIdclient.deleteIdentityPool(request) println(The identity pool was successfully deleted) } }这是一个典型的破坏性操作删除后该身份池及其关联配置将不可恢复生产环境请勿随意执行。3. 列举身份池listIdentityPools文件ListIdentityPools.kt无命令行参数直接运行。实现展示了分页字段maxResults的用法suspend fun getPools() { val request ListIdentityPoolsRequest { maxResults 10 } CognitoIdentityClient.fromEnvironment { region us-east-1 }.use { cognitoIdentityClient - val response cognitoIdentityClient.listIdentityPools(request) response.identityPools?.forEach { pool - println(The identity pool name is ${pool.identityPoolName}) } } }maxResults控制单次返回的池数量上限示例取 10。当身份池数量较多时可从 SDK 分页器进一步翻页获取全部结果。4. 列举身份池中的身份listIdentities文件ListIdentities.kt命令行运行方式identityPoolId例如us-east-1:00eb915b-c521-417b-af0d-ebad008axxxx。suspend fun listPoolIdentities(identityPoolId: String?) { val request ListIdentitiesRequest { this.identityPoolId identityPoolId maxResults 15 } CognitoIdentityClient.fromEnvironment { region us-east-1 }.use { cognitoIdentityClient - val response cognitoIdentityClient.listIdentities(request) response.identities?.forEach { identity - println(The identity Id value is ${identity.identityId}) } } }ListIdentitiesRequest同时设置了identityPoolId与maxResults上限 15返回结果中的identities列表携带每个身份的identityId。这是排查哪些客户端身份正在使用某个身份池的常用手段。二、用户池操作CognitoIdentityProviderClient 七个示例以下示例均使用CognitoIdentityProviderClient管理用户池user pool及其用户目录。1. 创建用户池createUserPool文件CreateUserPool.kt命令行运行方式userPoolName用户池名称。suspend fun createPool(userPoolName: String): String? { val request CreateUserPoolRequest { this.poolName userPoolName } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - val createUserPoolResponse cognitoClient.createUserPool(request) return createUserPoolResponse.userPool?.id } }CreateUserPoolRequest在示例中仅设置了poolName其余大量策略参数密码策略、Schema、MFA 配置等均采用 AWS 默认值。createUserPoolResponse.userPool?.id返回新池 ID它是后续所有用户池操作的入参。2. 删除用户池deleteUserPool文件DeleteUserPool.kt命令行运行方式userPoolId。suspend fun delPool(userPoolId: String) { val request DeleteUserPoolRequest { this.userPoolId userPoolId } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - cognitoClient.deleteUserPool(request) print($userPoolId was successfully deleted) } }删除用户池属于高危破坏性操作会连同池内全部用户一并移除务必谨慎。3. 获取用户池信息describeUserPool文件DescribeUserPool.kt命令行运行方式userPoolId。suspend fun describePool(userPoolId: String) { val request DescribeUserPoolRequest { this.userPoolId userPoolId } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - val response cognitoClient.describeUserPool(request) val poolARN response.userPool?.arn println(The user pool ARN is $poolARN) } }describeUserPool返回用户池的完整配置快照示例仅提取了userPool.arn并打印。该 ARN 常用于给其他服务如 API Gateway、Lambda授予访问用户池的权限。4. 列举用户池listUserPools文件ListUserPools.kt无命令行参数直接运行suspend fun getAllPools() { val request ListUserPoolsRequest { maxResults 10 } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - val response cognitoClient.listUserPools(request) response.userPools?.forEach { pool - println(The user pool name is ${pool.name}) } } }与listIdentityPools类似通过maxResults控制单页返回数量。5. 列举用户池客户端listUserPoolClients文件ListUserPoolClients.kt该文件虽未被 README 单列但被 CognitoKotlinTest.kt 的测试 4、测试 5 直接调用属于身份提供商场景的重要补充。命令行运行方式userPoolId。suspend fun listAllUserPoolClients(userPoolId: String) { val request ListUserPoolClientsRequest { this.userPoolId userPoolId } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - val response cognitoClient.listUserPoolClients(request) response.userPoolClients?.forEach { pool - println(Client ID is ${pool.clientId}) println(Client Name is ${pool.clientName}) } } }clientId与clientName正是后续SignUpUser、CognitoMVP场景中注册和登录所必需的凭据因此该示例是打通用户池 → 应用客户端链路的关键一环。6. 管理员创建用户adminCreateUser文件CreateUser.kt命令行运行方式userPoolId userName email password共 4 个参数。suspend fun createNewUser( userPoolId: String, name: String, email: String, password: String, ) { val attType AttributeType { this.name email value email } val request AdminCreateUserRequest { this.userPoolId userPoolId username name temporaryPassword password userAttributes listOf(attType) } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { cognitoClient - val response cognitoClient.adminCreateUser(request) println(User ${response.user?.username} is created. Status is ${response.user?.userStatus}) } }要点说明通过AttributeType给新用户附加email属性用于账户验证。temporaryPassword表示这是临时密码密码规则要求包含大写字母、小写字母、数字及至少一个特殊字符用户首次登录时通常会被要求设置新密码。adminCreateUser是管理员通道不需要用户先完成自助注册适合后台批量开号场景。返回的userStatus可用于判断用户当前处于FORCE_CHANGE_PASSWORD等状态。7. 自助注册用户signUp文件SignUpUser.kt命令行运行方式clientId secretkey userName password email共 5 个参数。clientId与secretkeyApp Client Secret均可从 AWS 管理控制台的应用客户端设置中获取。suspend fun signUp( clientIdVal: String, secretKey: String, userName: String, passwordVal: String, email: String, ) { val attributeType AttributeType { this.name email this.value email } val attrs mutableListOfAttributeType() attrs.add(attributeType) val secretVal calculateSecretHash(clientIdVal, secretKey, userName) val request SignUpRequest { userAttributes attrs username userName clientId clientIdVal password passwordVal secretHash secretVal } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { identityProviderClient - identityProviderClient.signUp(request) println(User has been signed up) } }与adminCreateUser不同signUp是面向终端用户的自助注册通道且当应用客户端配置了 Secret 时必须在请求中携带secretHash。示例提供了完整的Secret Hash 计算函数基于 HMAC-SHA256fun calculateSecretHash( userPoolClientId: String, userPoolClientSecret: String, userName: String, ): String { val macSha256Algorithm HmacSHA256 val signingKey SecretKeySpec( userPoolClientSecret.toByteArray(StandardCharsets.UTF_8), macSha256Algorithm, ) try { val mac Mac.getInstance(macSha256Algorithm) mac.init(signingKey) mac.update(userName.toByteArray(StandardCharsets.UTF_8)) val rawHmac mac.doFinal(userPoolClientId.toByteArray(StandardCharsets.UTF_8)) return Base64.getEncoder().encodeToString(rawHmac) } catch (e: UnsupportedEncodingException) { println(e.message) } return }实现原理以userPoolClientSecret作为 HMAC 密钥将userName与userPoolClientId拼接后经HmacSHA256计算摘要再以 Base64 编码输出。凡是注册、确认注册、登录等涉及客户端 Secret 的请求都必须附带这个 hash。三、端到端场景CognitoMVP 与 TOTP MFA文件CognitoMVP.kt 是本目录唯一的完整场景示例演示注册新用户 为 MFA 绑定认证器 App的完整流程。其注释明确说明运行前需要先用仓库提供的 AWS CDK 脚本resources/cdk/cognito_scenario_user_pool_with_mfa创建好带 MFA 的用户池并从中取得clientId与poolId作为命令行参数。场景执行流程命令行运行方式clientId poolId。程序随后通过控制台交互依次完成以下 9 个步骤signUp注册用户携带 email 属性见signUp(clientId, userName, password, email)adminGetUser查询用户确认状态见getAdminUserresendConfirmationCode若用户要求重新发送验证码则调用见resendConfirmationCodeconfirmSignUp输入邮箱收到的确认码完成确认见confirmSignUpadminInitiateAuth发起管理员认证登录此时返回的 Challenge 为MFA_SETUP提示需要配置 TOTP见checkAuthMethodassociateSoftwareToken生成 TOTP 私钥可用于 Google Authenticator见getSecretForAppMFAverifySoftwareToken输入认证器显示的 6 位动态码完成 TOTP 校验并登记 MFA见verifyTOTPadminInitiateAuth再次登录此时 Challenge 变为SOFTWARE_TOKEN_MFAadminRespondToAuthChallenge提交 6 位动态码换取认证令牌见adminRespondToAuthChallenge。关键认证代码管理员密码认证注意AuthFlowType.AdminUserPasswordAuth与USERNAME/PASSWORD参数对suspend fun checkAuthMethod( clientIdVal: String, userNameVal: String, passwordVal: String, userPoolIdVal: String, ): AdminInitiateAuthResponse { val authParas mutableMapOfString, String() authParas[USERNAME] userNameVal authParas[PASSWORD] passwordVal val authRequest AdminInitiateAuthRequest { clientId clientIdVal userPoolId userPoolIdVal authParameters authParas authFlow AuthFlowType.AdminUserPasswordAuth } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { identityProviderClient - val response identityProviderClient.adminInitiateAuth(authRequest) println(Result Challenge is ${response.challengeName}) return response } }关联 TOTP 软件令牌返回的session需要传递给后续校验步骤suspend fun getSecretForAppMFA(sessionVal: String?): String? { val softwareTokenRequest AssociateSoftwareTokenRequest { session sessionVal } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { identityProviderClient - val tokenResponse identityProviderClient.associateSoftwareToken(softwareTokenRequest) val secretCode tokenResponse.secretCode println(Enter this token into Google Authenticator) println(secretCode) return tokenResponse.session } }校验 TOTP 并登记 MFAsuspend fun verifyTOTP( sessionVal: String?, codeVal: String?, ) { val tokenRequest VerifySoftwareTokenRequest { userCode codeVal session sessionVal } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { identityProviderClient - val verifyResponse identityProviderClient.verifySoftwareToken(tokenRequest) println(The status of the token is ${verifyResponse.status}) } }响应SOFTWARE_TOKEN_MFA挑战并换取最终认证结果suspend fun adminRespondToAuthChallenge( userName: String, clientIdVal: String?, mfaCode: String, sessionVal: String?, ) { println(SOFTWARE_TOKEN_MFA challenge is generated) val challengeResponsesOb mutableMapOfString, String() challengeResponsesOb[USERNAME] userName challengeResponsesOb[SOFTWARE_TOKEN_MFA_CODE] mfaCode val adminRespondToAuthChallengeRequest AdminRespondToAuthChallengeRequest { challengeName ChallengeNameType.SoftwareTokenMfa clientId clientIdVal challengeResponses challengeResponsesOb session sessionVal } CognitoIdentityProviderClient.fromEnvironment { region us-east-1 }.use { identityProviderClient - val respondToAuthChallengeResult identityProviderClient.adminRespondToAuthChallenge(adminRespondToAuthChallengeRequest) println(respondToAuthChallengeResult.getAuthenticationResult() ${respondToAuthChallengeResult.authenticationResult}) } }该场景完整覆盖了 Cognito 用户池最常见的生产链路自助注册 → 邮件确认 → 管理员登录 → TOTP 绑定 → MFA 挑战应答是构建移动端/Web 端安全登录体系的直接参考实现。四、运行 Kotlin 示例README 建议使用Gradle搭建 AWS SDK for Kotlin 项目的构建与运行环境gradlew或本地 Gradle。本目录的 build.gradle.kts 提供了可直接复用的构建配置使用 Kotlin JVM 插件Kotlin 2.1.0与application插件目标/源兼容 Java 17jvmTarget 17通过aws.sdk.kotlin:bom:1.5.63统一管理 AWS SDK 版本依赖cognitoidentityprovider、cognitoidentity、secretsmanager及 OkHttp/CRT HTTP 客户端引擎测试侧引入 JUnit Jupiter 5.9.2并启用useJUnitPlatform()。运行单个示例时传入对应命令行参数即可例如./gradlew run --argsmy-identity-pool-name ./gradlew run --argsus-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx user1 user1example.com Password123!五、用 JUnit 5 测试这些示例测试文件与运行方式测试类位于 src/test/kotlin/CognitoKotlinTest.kt名为CognitoKotlinTest基于 JUnit 5 编写。你既可以在 IntelliJ 等 IDE 中直接执行也可以在命令行用 Maven 运行mvn test每个测试通过logger.info输出Test N passed例如Test 3 passed测试类使用TestInstance(PER_CLASS)、TestMethodOrder(OrderAnnotation::class)与Order(n)控制执行顺序共 11 个用例创建用户池 → 管理员建用户 → 列举用户池 → 列举/描述用户池客户端 → 删除用户池 → 创建身份池 → 列举身份池 → 列举身份 → 删除身份池覆盖了身份池与用户池的完整生命周期。⚠️警告这些 JUnit 测试会操纵真实的 AWS 资源可能产生账户费用请仅在测试专用环境中运行。测试配置config.properties 与 Secrets ManagerREADME 要求测试前在resources 文件夹的 config.properties中定义以下键值缺失任一键都会导致测试失败配置键用途userPoolName待创建的用户池名称CreateUserPool 测试usernameCreateAdminUser 测试使用的用户名emailCreateAdminUser 测试使用的用户邮箱clientNameCreateUserPoolClient 测试使用的客户端名称identityPoolNameCreateIdentityPool 测试使用的身份池名称confirmationCodeConfirmSignUp 测试使用的确认码值得补充的是从当前仓库源码看CognitoKotlinTest.kt 的setup()已演进为从 AWS Secrets Manager 读取test/cognito密钥经getSecretValues() Gson 反序列化为SecretValues数据类所需字段包括userPoolName、username、email、clientName、identityPoolName、identityId、appId、existingUserPoolId、existingIdentityPoolId、providerName、existingPoolName、clientId、secretkey、password以及 MVP 场景专用的poolIdMVP/clientIdMVP/userNameMVP/passwordMVP/emailMVP。也就是说当前版本的测试配置以 Secrets Manager 为准config.properties 可视为该方案的早期形式——两种方式都要求提前准备真实可用的资源与凭据。测试还演示了username拼接UUID.randomUUID()的技巧避免并发或重复运行时用户名冲突。六、深入学习路径逐一阅读 kotlin/services/cognito/src/main/kotlin/com/kotlin/cognito 下 13 个 Kotlin 源文件代码中均带有snippet-start/snippet-end标记方便在文档系统中按片段引用结合 build.gradle.kts 理解 SDK 版本与依赖管理方式对照 CognitoKotlinTest.kt 的用例顺序理解各 API 调用之间的依赖关系与资源生命周期如需深入理解 Amazon Cognito 用户池的架构与概念身份池、用户池、客户端、MFA 等可查阅 AWS 官方 Amazon Cognito 开发者指南与 AWS SDK for Kotlin 开发者指南。版权说明本目录示例代码版权归 Amazon.com, Inc. 或其关联公司所有基于 Apache-2.0 许可发布SPDX-License-Identifier: Apache-2.0。赞分享示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载相关推荐AWS SDK for Java V2 操作 Amazon Cognito用户池、身份池与 MFA 场景实战指南AWS SDK for Java V2 操作 Amazon Cognito用户池、身份池与 MFA 场景实战指南 导读 本文基于 aws doc sdk ex示例工程教程后端AWS SDK for Javav1为 Amazon Cognito 用户池启用短信 MFA 的完整实战指南AWS SDK for Javav1为 Amazon Cognito 用户池启用短信 MFA 的完整实战指南 导读 Amazon Cognito 用户池U示例工程教程后端使用 AWS SDK for JavaScript (v3) 实战 Amazon Cognito Identity Provider用户池认证、MFA 与 Lambda 触发器使用 AWS SDK for JavaScript v3 实战 Amazon Cognito Identity Provider用户池认证、MFA 与 Lam示例工程教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
捷码AI三分钟生成毕设初稿:图表、源码、文档全解析 1. 这套工具到底解决了什么问题做过毕设或者带过课设的人都清楚,最折磨人的往往不是写代码本身,而是那些围绕代码衍生出来的一整套文档体系。开题报告要画E-R图、功能结构图、数据流程图,中期检查要补系统流程图、类图、时序图、用例图&#… · 2026/9/26 11:37:45
【原理】从用户消息到 AI 回复:OpenClaw 完整执行链路解析与 TaoToken 配置骨架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:37:45
AI让唐代仕女跳舞:图生视频与姿态控制实战教程 最近短视频平台上有一类内容特别容易刷屏:博物馆里的唐代仕女忽然“活”了过来,跟着音乐节奏跳舞、转圈、拂袖;古画里的簪花少女变成动画人物,神态动作都非常自然。很多读者在后台问,这种视频到底怎么做的?… · 2026/9/26 14:37:56
从提示词到产线:多智能体代码审查的工程化落地实践 1. 从提示词到产线:为什么代码审查需要多智能体 代码审查这件事,写过几年代码的人都有体会。它表面上是一个“看代码”的动作,实际上背后牵扯的东西特别多:风格一致性、潜在缺陷、安全边界、可维护性、团队规范、上下文理解&#… · 2026/9/26 14:37:56
TeamAI-CLI:腾讯开源的团队级AI Agent中间层,让AI能力成为团队资产 1. 为什么团队需要一个 AI Agent 中间层1.1 从个人效率工具到团队能力资产过去一年多,我身边几乎每个开发者都在用 AI 编程助手。有人用 Claude CLI,有人用 Codex CLI,有人用各种 IDE 插件,每个人都在自己的终端里攒了一堆 prompt… · 2026/9/26 14:37:56
前端开发环境搭建:Node.js、npm、VSCode 配 TaoToken 统一 Key 通道 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 14:37:50
设计在线文件分享系统:从分片上传到对象存储的核心决策 Design an Online File-sharing System | Preparation很多人拿到"设计一个在线文件分享系统"这道题,第一反应是画一张架构图:前端、后端、对象存储、CDN,再加上一个消息队列,看起来五脏俱全。但到了追问环节,… · 2026/9/26 14:37:43
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46