协作办公
Android 应用用 Credential…
适用于 Android 客户端集成 Google 等可信提供方的数字凭证,在账号创建、恢复、重认证等流程中无 OTP 获取已验证邮箱。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
Android 应用用 Credenti特定
解决思路
- 阅读并参考 fundamentals:references/android/identity/digital-credentials/email-verification.md、references/android/identity/digital-credentials/email-verification-implementation.md,并查阅术语 dcql_query、UserInfoCredential、GetDigitalCredentialOption;同时参考 OpenID4VP、Digital Credentials Demo、W3C Verifiable Credentials、SD-JWT、mdoc 标准与示例。
- 确认 requirements:Minimum SDK 28 (Android 9),Google Play services version 25.49.x 或更高。
- 适用于 Account Creation/Sign-up、Account Recovery、Re-authentication;注意 Workspace Accounts 不签发可验证凭证;非 @gmail.com 无 freshness claim,需额外 challenge 如 OTP。
- 明确范围:该技能只做 Android 客户端集成,不实现服务端密码学校验;服务端校验必须由后端实现。
- 在代码库中探索 use cases:搜索 SignUpScreen、Email address、Recover Account、Account Recovery、Forgot password?、Delete Account。
- 识别集成点 1:搜索导航路由/目的地,关键词 signup、registration、create_account、forgot_password、recovery、verify_email;搜索 NavHost 或 composable destinations。
- 识别集成点 2:定位认证 ViewModel,关键词 SignUpViewModel、AuthViewModel、RegistrationRepository;查找方法 onCreateAccount、onRecoverAccount、validateEmail。
- 识别集成点 3:查找敏感操作重认证,关键词 ChangePassword、UpdatePayment、DeleteAccount、UpdateDetails、EditUserDetails。
- 在 app 的 build.gradle 中添加 Credential Manager 依赖:Kotlin 使用 implementation(androidx.credentials:credentials:1.7.0-alpha03) 和 implementation(androidx.credentials:credentials-play-services-auth:1.7.0-alpha03);Groovy 使用 implementation androidx.credentials:credentials:1.7.0-alpha03 和 implementation androidx.credentials:credentials-play-services-auth:1.7.0-alpha03。
- 用 app 或 activity context 初始化 Credential Manager:private val credentialManager = CredentialManager.create(context)。
- 生成每次请求唯一且密码学安全的 nonce:val nonce = generateSecureRandomNonce();禁止跨请求复用。
- 构造 OpenID4VP request JSON:包含 requests 数组(文档提到当前 providers 支持 digital 到 requests 外层包装);每个 request 含 protocol: openid4vp-v1-unsigned、data、response_type: vp_token、response_mode: dc_api、nonce、dcql_query。
- 在 dcql_query.credentials 中指定 credential:id: user_info_query、format: dc+sd-jwt、meta.vct_values: [UserInfoCredential];claims paths 包含 email、name、given_name、family_name、picture、hd、email_verified。
- 在请求中处理 email_verified 与 hd:email_verified 为 Boolean 表示邮箱是否验证;hd 为空且 email_verified 为 true 表示授权 Google Account;Google Workspace Accounts 不签发 verifiable credentials;对 hd 做 future-proof 处理;非 @gmail.com 无 freshness claim,考虑额外 OTP。
- 不要构造只包含隐藏字段 hd 和 email_verified 的请求;这些字段在 Credential Manager 内置 UI 中隐藏,这种请求会返回 GetCredentialCancellationException。
- 用 GetDigitalCredentialOption(requestJson = openId4vpRequest) 包装请求,再创建 GetCredentialRequest(listOf(getDigitalCredentialOption)),然后调用 getCredential()。
- 使用 Credential Manager 内置 UI 展示请求:val result = credentialManager.getCredential(activity, request);用 try/catch 处理异常;在 when 中判断 result.credential。
- 当 credential 是 DigitalCredential 时,取 credential.credentialJson 作为 responseJsonString;否则处理 unexpected state。
- 注意 Digital Credentials 没有 Sign in with Google 的 preferImmediatelyAvailableCredentials 等价物;无可用可验证凭证时用户会看到 No options available 类系统页面。
- 在客户端做初步解析以更新 UI(不是校验):解析外层 JSON 得到 data,再取 vp_token;用 vpToken.keys().next() 取 credentialId;从 vpToken.getJSONArray(credentialId).getString(0) 取 raw SD-JWT;用本地 SdJwtParser.parse(rawSdJwt) 得到 claims;用 VerifiedUserInfo 存 email 和 displayName。
- 兼容响应格式变化:从 2026 年 8 月起 response JSON 严格匹配 W3C 标准,包含 data 和 protocol,OpenID4VP vp_token 嵌在 data;旧格式直接持有 vp_token。过渡期客户端解析和服务端校验都要处理两种格式;2026-08 后新集成只用新格式。
- 处理响应示例字段:protocol、data.vp_token(key 匹配 dcql_query 的 id)、SD-JWT string;解析后的 claims 包含 cnf、exp、iat、iss、vct、email、email_verified、given_name、family_name、name、picture、hd。
- 强烈建议收到已验证邮箱后触发 Credential Manager 的 passkey creation;若尚无 passkey,提供 passkey 创建选项。
- 服务端验证用于账号创建:将完整 responseJsonString 和原始 nonce 发送到服务端新 endpoint;在创建账号或登录前完成密码学校验;客户端发送 raw response(含 vp_token)和 original nonce。
- 服务端必须校验 issuer:iss 字段匹配 https://verifiablecredentials-pa.googleapis.com。
- 服务端必须校验签名:使用 https://verifiablecredentials-pa.googleapis.com/.well-known/vc-public-jwks 的 public keys (JWKs) 校验 SD-JWT 签名。
- 服务端必须校验 presenter identity:校验 cnf 字段和 Key Binding (kb) signature,确认凭证由原始签发设备分享,防止拦截或跨设备使用。
- 服务端校验 nonce 以防止 replay attacks;使用标准库如 @sd-jwt/sd-jwt-vc(Node.js)按 OpenID4VP 规范执行验证。
- 在服务端代码中,用自定义 createAccountWithVerifiedCredentials(responseJsonString, nonce) 完成服务端验证和账号创建;服务端返回新账号信息后解析 claims 并用 VerifiedUserInfo 存 email 和 displayName;异常按需处理。
- 在实现中留下 TODO 给开发者处理 app 的服务端校验和解析;客户端解析结果不能用于安全敏感操作,只可用于 UI 参考。
- API 调用成功后导航用户到 home screen,并显示包含用户详情的 snackbar 仅供 reference。
- 若需要在 WebView 中工作,实现 JavaScript bridge (JS Bridge),让 WebView 对象通知 native app,再由 native app 调用 Credential Manager API。
- 安全要求:绝不信任客户端解析的 claims 用于账号创建等安全敏感操作;把完整 raw responseJsonString 和原始 nonce 发到服务端做完整验证。
- 安全要求:每个请求生成唯一密码学安全 nonce,绝不复用 nonce 以防 replay attacks。
- 安全要求:服务端必须校验 issuer (iss)、SD-JWT signature,并用 cnf 字段校验 presenter identity。
- 使用 VerifiedUserInfo data class 存储解析后的 name 和 email。
- 假设有本地 SdJwtParser 解析 raw SD-JWT 并返回 JSONObject。
- 构造 Digital Credential Request 并展示给用户;确保 request JSON structure 按文档 references/android/identity/digital-credentials/email-verification-implementation.md。
适用边界 · 注意事项
- Google Workspace Accounts 不签发可验证凭证,不能使用此流程。
- 非 @gmail.com 地址没有 freshness claim;若需确认当前控制权,应额外加 OTP/挑战,不能只靠该凭证。
- 不满足 SDK 28 / GMS 25.49.x+,或无法实现服务端密码学校验时不应使用;客户端解析不能用于安全敏感操作。