使用 WebAuthn API 创建凭据时处理用户取消

Handling user cancellation when creating credentials with WebAuthn API

提问人:Gabriel Andrade 提问时间:11/9/2023 最后编辑:Gabriel Andrade 更新时间:11/11/2023 访问量:92

问:

我正在尝试为应用程序实现 FIDO 载入应用程序。要使用 WebAuthn API 创建用户凭据,我使用:

navigator.credentials.create(options)

这将返回一个 promise,该 promise 在允许时使用用户凭据进行解析。但是,如果用户取消凭据创建,而不是允许,则会引发 with with name。DOMExceptionNotAllowedError

在应用中,当用户单击一个按钮时,将触发对 Web 身份验证 API 的凭据创建调用,该按钮具有一个 onClick,该按钮指向一个函数,该函数在尝试创建凭据之前也会切换加载动画。为了提供良好的用户体验,当用户单击取消时,我想处理此异常,关闭加载动画,然后显示按钮以再次创建凭据。

我想知道处理这种情况时的最佳实践。我对这个流程的了解还不够多,甚至不知道将调用包装在 try-catch 中然后使用名称处理每个错误是否安全,或者是否在其他情况下也抛出此错误,例如,当无法联系用户设备时,在这种情况下,这可能会导致实际想要允许凭据创建的用户被困在单击创建凭据的无限循环中, 单击“允许”,获取 NotAllowedError,再次显示创建凭据的按钮。NotAllowedError

try {
    const credentials = await navigator.credentials.create(options)
    // do whatever
} catch (err) {
    if (err instanceof DOMException && err.name === "NotAllowedError") {
        // handle user cancelation
        return
    }
    // handle other scenarios
}

长话短说,我想专门处理这种用户取消的情况,以及我会以其他方式处理错误的任何其他情况。

JavaScript 错误处理 多因素身份验证 Webauthn Fido

评论


答:

1赞 agl 11/11/2023 #1

NotAllowedError在许多情况下都会返回,但总的来说,用户都放弃了 WebAuthn UI。创建时唯一有意义的错误是 ,这表示用户尝试在平台身份验证器上创建凭据,该身份验证器已将其中一个凭据包含在排除列表中。InvalidStateError

如果您担心可能会同步返回,而无需用户交互,那么这是可能的。至少在 Chromium 中,这种情况可能会在已插入的安全密钥返回无效消息时发生NotAllowedError

1赞 VonC 11/11/2023 #2

由于 NotAllowedError 可能发生在 WebAuthn UI 交互不完整或不正确的各种情况下,因此以不假定它始终是直接用户取消的方式处理此错误非常重要。
您可能希望向用户发送一条消息,指示凭据创建过程未完成,而不是明确指出他们已取消该过程。

正如 agl 所提到的,处理 InvalidStateError 也很重要。
当尝试创建已在平台身份验证器的排除列表中的凭据时,会发生该错误。这需要单独处理,可能会向用户发送特定的错误消息。

在可能同步返回的情况下(例如,由于来自已插入的安全密钥的无效消息),在 try-catch 块中捕获和处理此问题仍然是合理的。
但是,其他日志记录或更详细的错误消息可能有助于调试和用户信息。
NotAllowedError

您的函数是:createCredentials

async function createCredentials() {
    try {
        startLoadingAnimation();

        const credentials = await navigator.credentials.create(options);
        
        stopLoadingAnimation();
        // Handle successful credentials creation
    } catch (err) {
        stopLoadingAnimation();

        if (err instanceof DOMException) {
            if (err.name === "NotAllowedError") {
                // Handle incomplete interaction with WebAuthn UI
                // Use a generic message like "Process not completed"
            } else if (err.name === "InvalidStateError") {
                // Handle the specific case of InvalidStateError
                // Use a message like "Credential already exists"
            }
        } else {
            // Handle other errors
        }
    } finally {
        // Reset UI / Display appropriate messages
    }
}

这样一来,错误处理将变得更加可靠,并考虑到可能导致 的各种方案,以及专门的处理。这意味着更好的用户体验,并有助于调试和故障排除。NotAllowedErrorInvalidStateError

评论

0赞 Gabriel Andrade 11/16/2023
只是希望 WebAuthn API 能提供这样的选项。作为 MVP,这很好,但我们肯定会尽快实现原生化。
1赞 VonC 11/16/2023
@GabrielAndrade我同意,在基于 Web 的环境中处理各种错误场景是......复杂。至少,即使决定使用本机,维护基于 Web 的解决方案作为后备或替代方案也可能是有益的,特别是对于可能出于任何原因无法使用本机应用程序的用户。双重方法可以增加用户覆盖面。但是,是的,WebAuthn API 需要包含该选项。