iOS 15下WebAuthn捕获报错后仍弹出FaceID提示的问题咨询
问题1:错误抛出后仍显示验证弹窗是否为iOS 15系统Bug
该现象是iOS 15及部分早期iOS 16版本搭载的WebKit内核的已知WebAuthn实现偏差,不属于代码逻辑问题。
按照W3C WebAuthn标准规范,InvalidStateError(对应当前RP下已存在同用户绑定凭据的状态)应当在用户完成本地身份验证(即完成Face ID校验、明确授权注册操作)后才抛出。但iOS端WebKit的实现逻辑存在时序问题:调用navigator.credentials.create()时,内核会并行执行两个操作——一是提前在本地校验当前RP ID下是否已存在对应用户的有效凭据,校验到存在就立刻抛出InvalidStateError;二是触发系统级生物验证弹窗拉起,两个流程没有做状态联动,抛出错误时不会主动取消已经触发的弹窗拉起逻辑,就会出现错误已返回、Face ID弹窗仍遮挡页面的情况。
Windows平台的Chromium内核实现严格遵循了规范时序:先拉起验证弹窗,等用户完成生物校验后再校验本地凭据存在性,最后抛出对应错误,因此表现和首次注册流程一致。
问题2:可行的体验规避方案
目前有三个落地成本不同的方案,可以根据自身业务情况选择:
- 最简便的兜底方案:捕获到
InvalidStateError时不要立刻执行页面跳转/注册成功逻辑,增加1.5-2秒的固定延迟后再渲染注册完成页。Web层面没有权限监听系统级生物验证弹窗的消失事件,这个延迟时长刚好覆盖iOS弹窗从触发到自动回收的周期,实测可以完全避免完成页被遮挡的问题,不需要改动现有核心逻辑。 - 根源规避方案:除了在cookie中存储credential-id之外,额外在
localStorage或者IndexedDB中存一个轻量的「当前设备已完成WebAuthn注册」标记。普通用户手动清理站点数据时,很少会单独清cookie而保留其他存储,前置校验到该标记存在时,直接走补生成新cookie的逻辑,不需要调用navigator.credentials.create()触发注册流程,从根源上避开这个时序bug。注意这个标记只能做前置判断,不能替代原有InvalidStateError的捕获兜底逻辑,避免用户清完全部站点数据后流程异常。 - 长期优化方案:如果业务改造成本可接受,可以改用可发现凭据(discoverable credentials),注册完成后通过
navigator.credentials.get()传入mediation: 'silent'参数做静默预检,不需要触发生物验证弹窗就能判断本地是否存在对应凭据,不用等create接口抛错再做处理,不过这个方案需要同步调整后端的凭据校验逻辑。
问题3:官方反馈渠道
该类Web标准实现偏差问题,直接通过苹果开发者官方的反馈助理提交Bug报告即可,提交时附上最小可复现Demo、对应系统版本、机型、清晰的复现步骤,WebKit团队会跟进处理这类实现问题。
内容的提问来源于stack exchange,提问作者Nina
相关产品推荐
相关产品推荐

