概述目标:以WebAuthn在浏览器中创建/使用凭证,实现无密码身份验证;结合Passkeys跨设备同步提升易用性。适用:面向公众的账号系统、企业SSO、敏感操作二次验证。核心与实战注册(创建凭证):// 获取注册选项(服务端生成) const options = await (await fetch('/webauthn/register/options')).json(); options.challenge = Uint8Array.from(atob(options.challenge), c => c.charCodeAt(0)); options.user.id = Uint8Array.from(atob(options.user.id), c => c.charCodeAt(0)); options.pubKeyCredParams = [{ type: 'public-key', alg: -7 }]; // ES256 options.authenticatorSelection = { residentKey: 'preferred', userVerification: 'required' }; const cred = await navigator.credentials.create({ publicKey: options }); await fetch('/webauthn/register/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: cred.id, rawId: btoa(String.fromCharCode(...new Uint8Array(cred.rawId))), type: cred.type, response: { attestationObject: btoa(String.fromCharCode(...new Uint8Array(cred.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(cred.response.clientDataJSON))) } }) }); 登录(获取断言):const request = await (await fetch('/webauthn/login/options')).json(); request.challenge = Uint8Array.from(atob(request.challenge), c => c.charCodeAt(0)); request.allowCredentials = request.allowCredentials.map(c => ({ id: Uint8Array.from(atob(c.id), ch => ch.charCodeAt(0)), type: 'public-key' })); request.userVerification = 'required'; const assertion = await navigator.credentials.get({ publicKey: request }); await fetch('/webauthn/login/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: assertion.id, rawId: btoa(String.fromCharCode(...new Uint8Array(assertion.rawId))), type: assertion.type, response: { authenticatorData: btoa(String.fromCharCode(...new Uint8Array(assertion.response.authenticatorData))), clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(assertion.response.clientDataJSON))), signature: btoa(String.fromCharCode(...new Uint8Array(assertion.response.signature))), userHandle: assertion.response.userHandle && btoa(String.fromCharCode(...new Uint8Array(assertion.response.userHandle))) } }) }); 示例服务端校验要点:-- 注册:验证clientDataJSON.type='webauthn.create',origin与rpId匹配;解析attestationObject并提取公钥与签数;保存credentialId与publicKey。 -- 登录:验证clientDataJSON.type='webauthn.get';使用存储的publicKey对(signature, clientDataJSON, authenticatorData)进行验签;检查signCount递增抵御重放。 RP设置与跨域:-- rp.id需与站点有效域匹配(如app.example.com);跨子域需正确设置rpId与origin。 验证与监控浏览器侧:控制台捕获`navigator.credentials`异常;网络面板观察与后端交互与状态码。后端侧:记录注册/登录失败原因(origin/rpId/签名/计数),并监控成功率与异常型号。常见误区Base64URL与ArrayBuffer互转错误导致验证失败;需严格按字节序转换。rpId错误或与origin不一致;浏览器会拒绝创建/获取凭证。未使用`userVerification='required'`导致安全性下降;根据风险等级调整策略。结语通过WebAuthn与Passkeys可在提升安全性的同时优化用户体验,关键在于严格的参数与跨端校验流程落地。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部