web

WebAuthn认证

生物识别登录认证

Posted by Jason on July 10, 2025

现在登录的网站越来越多,每个网站都需要账户密码。

我又不喜欢把每个网站的密码都设置成一样的。

我又不喜欢记住密码。

能不能不用密码直接登录啊?

例如直接扫脸,或者指纹识别就好了。

当然可以,这就是WebAuthn认证。

直接上流程图

@startuml
actor 用户
participant 浏览器
participant 应用服务器
participant "认证器"

== WebAuthn 注册流程 ==

用户 -> 浏览器 : 注册并开启生物认证
浏览器 -> 应用服务器 : 请求注册选项(用户名等)
应用服务器 -> 浏览器 : 返回 challenge、RP、用户信息、公钥算法等

浏览器 -> "认证器" : navigator.credentials.create()
"认证器" -> 用户 : 弹出注册认证器(指纹/面部/安全密钥)
"认证器" --> 浏览器 : 返回凭证(公钥、签名、clientDataJSON 等)

浏览器 -> 应用服务器 : 提交凭证信息
应用服务器 -> 应用服务器 : 验证凭证并保存公钥
应用服务器 -> 浏览器 : 注册成功提示

== WebAuthn 无用户名登录(可发现凭证) ==

用户 -> 浏览器 : 生物认证登录
浏览器 -> 应用服务器 : 请求生成 login challenge(不带用户名)
应用服务器 -> 浏览器 : 返回 challenge 和 RP 信息

浏览器 -> "认证器" : navigator.credentials.get()(不指定用户名)
"认证器" -> 用户 : 用户选择账号并进行认证(指纹、人脸等)
"认证器" --> 浏览器 : 返回已选账号的签名凭证(凭证ID、公钥ID)

浏览器 -> 应用服务器 : 提交凭证信息
应用服务器 -> 应用服务器 : 验证签名 + 凭证ID 匹配用户
应用服务器 --> 浏览器 : 登录成功(返回 token/session)

@enduml

webauthn流程图

体验地址

由Claude生成。点击链接体验

其他内容

其实主要的就是两个内容,

  1. 调用浏览器创建秘钥(navigator.credentials.create)

  2. 调用浏览器获取用户秘钥(navigator.credentials.get)

参数不同,呈现的效果也不一样。具体可以参考这里

参考地址