You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android集成Passkeys调用getCredentialAsync()触发NoCredentialException问题

解决Passkey验证时的NoCredentialException问题

以下是针对注册成功但验证触发NoCredentialException问题的排查和解决步骤:

1. 确保验证请求与注册请求的RP ID完全匹配

RP ID(依赖方标识符)是Passkey匹配的核心标识,注册和验证时的RP ID必须完全一致:

  • 不能存在域名大小写差异(比如example.com和Example.com视为不同)
  • 不能混用主域名和子域名(比如app.example.com和example.com不匹配,除非注册时明确设置主域名作为RP ID)
  • 检查验证请求的JSON参数中,rpId字段是否和注册时的完全一致

2. 检查验证请求的allowCredentials参数(若使用)

如果验证请求中指定了allowCredentials数组:

  • 必须包含注册成功后服务器返回的凭证ID(id字段)
  • 注意Base64编码的一致性:注册时返回的凭证ID通常是URL安全的Base64编码,验证时要确保传入的编码格式完全相同(不要误转成普通Base64)
  • 如果不需要指定特定凭证,可移除allowCredentials参数,让系统自动匹配当前RP ID下的所有可用凭证

3. 确认客户端数据哈希(clientDataHash)处理一致

你注册时传入了clientDataHash = null,让系统自动处理哈希计算:

  • 验证时也必须保持clientDataHash = null,不要手动计算传入错误的哈希值
  • 如果需要自定义哈希,注册和验证时必须使用相同的算法和挑战值计算逻辑

4. 验证设备端是否正确存储了Passkey

注册成功后,检查设备的系统密码管理器:

  • 进入系统设置 > 密码与安全 > 密码管理器,查看是否存在对应RP ID的Passkey条目
  • 如果没有找到,说明注册流程中凭证未成功存储,需检查注册请求的参数是否存在错误(比如RP ID格式不正确,或凭证类型设置错误)

5. 检查验证请求的代码实现

以下是正确的getCredentialAsync调用示例,你可以对比排查自己的代码:

public void startAuthentication(PluginCall call) {
    String requestJson = call.getData().toString();
    String clientDataHash = null; // 和注册时保持一致,传null让系统处理

    GetPublicKeyCredentialRequest getRequest =
        new GetPublicKeyCredentialRequest(requestJson, clientDataHash);

    CancellationSignal cancellationSignal = new CancellationSignal();

    implementation.getCredentialManager().getCredentialAsync(
        getRequest,
        getActivity(),
        cancellationSignal,
        getContext().getMainExecutor(),
        new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
            @Override
            public void onResult(GetCredentialResponse result) {
                // 处理验证成功逻辑
                Log.d("AUTH SUCCESS", result.getCredential().getId());
            }

            @Override
            public void onError(GetCredentialException e) {
                if (e instanceof NoCredentialException) {
                    // 无匹配凭证的处理
                    Log.e("AUTH ERROR", "No matching passkey found");
                } else {
                    // 其他错误处理
                    JSObject ret = new JSObject();
                    ret.put("type", e.getMessage());
                    call.reject("auth_error", ret);
                }
            }
        });
}

6. 确认设备和环境支持

  • 确保设备运行Android 14及以上,或Android 10+且安装了最新版Google Play Services(提供Passkey支持)
  • 检查应用是否拥有BIOMETRIC_AUTHENTICATION权限,并且已申请运行时权限

内容的提问来源于stack exchange,提问作者Arigi Wiratama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:52:49