现在登录的网站越来越多,每个网站都需要账户密码。
我又不喜欢把每个网站的密码都设置成一样的。
我又不喜欢记住密码。
能不能不用密码直接登录啊?
例如直接扫脸,或者指纹识别就好了。
当然可以,这就是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
体验地址
由Claude生成。点击链接体验
其他内容
其实主要的就是两个内容,
-
调用浏览器创建秘钥(navigator.credentials.create)
-
调用浏览器获取用户秘钥(navigator.credentials.get)
参数不同,呈现的效果也不一样。具体可以参考这里