企业 Web 登录中的「双 UKey」场景实践:从单设备自动登录到多 Key 分流
登录页支持双 UKey:我们怎么改的
最近给质量系统登录页加了「双 Key」能力。用户机器上可能只插一把 UKey,也可能同时插两把——一把不用输 PIN,另一把必须输 PIN。改造前多 Key 场景容易拿错设备、PIN 策略对不上,有时页面还没提示就卡住了。这篇只聊思路和交互,证书、PIN、接口地址这些不写。
技术栈就是 Vue 2 + Ant Design Vue,本机有个 UKey 控件服务,前端再调自己的登录接口。
原先的问题
单 Key 时,页面加载后枚举到一把设备,直接读身份、调登录,用户几乎无感。
双 Key 时如果还按「永远取第一把」来,常见情况是:用户其实要用第二把,却走了免 PIN 通道;或者第二把该输 PIN 却没表单项;本地服务返回错误(一般以#开头的字符串),前端没兜住,控制台报错甚至白屏。
所以这次改动就三件事:先数有几把 Key;一把照旧自动登,两把再让人选;第一把和第二把走的读身份方式不一样。
三块各干各的
浏览器登录页:枚举、分支、表单、提示。不碰证书细节。
本机 UKey 服务:插了几把 Key、读证书里的登录标识。失败时经常直接给一串带#的文本或者数字,不是标准 HTTP 错误体。
业务后端:拿证书侧的身份标识去查系统用户,返回 token。一个证书绑多个系统账号时,返回列表,和域登录那套「选一个再进」是同一套路。
流程可以看成:
页面加载 → 开了 UKey 登录? → 枚举设备 → 只有 1 把:免 PIN 读身份 → 调登录接口 → 进系统或选用户 → 有 2 把:下拉选 Key → 选第二把才出 PIN 输入框 → 读身份 → 同上具体怎么走的
进来先数 Key
页面挂载后,如果后台配置打开了 UKey 登录,就先调本机的「枚举设备」。返回一般是几个序号用&连起来,比如1&2。
- 空、或者带
#:说明枚举失败,弹个错就停,别往下走。 - 只有一个序号:走自动登录,不出现选 Key 的表单。这点和改之前一致,老用户无感。
- 多个序号:把序号填进下拉框,等用户选完点确定。
入口这里就把单 Key / 多 Key 分开了,后面不用到处写「如果只有一把……」。
只有一把 Key
自动那条线:用「免 PIN」方式向本机服务要身份标识(别的系统已经验过口令时才能这么用),拿到以后再请求业务登录接口。后面不管单 Key 还是多 Key 手动选的,登录结果都走同一段处理逻辑,避免复制粘贴两套「判断几个用户」的代码。
两把 Key 让用户选
多 Key 时单独一块表单:先选「Key - 1 / Key - 2」。
- 选第一把:只校验选了哪把 Key,不显示 PIN,读身份走免 PIN。
- 选第二把:多出 PIN 输入框,提交时要校验 PIN,读身份走要带口令的那条接口。
切换回第一把时会把 PIN 输入清掉,免得上一把的 PIN 误带到下一把。
表单校验字段是动态的:没选第二把就不校验 PIN 这一项,Ant Design Vue 1.x 里用动态字段列表就能搞定。
登录接口回来以后
和域账号登录类似:
- 只查到一个系统用户:直接写 token、跳首页(有 redirect 就跟参数走)。
- 查到多个:页面上出用户列表,选完再点一次「UKey 账号登录」。
- 列表空或接口失败:必须给用户一句话,不能 loading 一直转。
和别的登录方式挤在同一页
这个登录页本来就有账号密码、域账号(URL 里带域用户标识那种)、顶部 Tab 切不同系统入口。UKey 流程跑起来会把「当前是域登录 UI」那个状态关掉,避免两套界面叠在一起。UKey 总开关关着的时候,还是原来的账号密码表单,方便测试环境不用插 Key。
踩过的坑
返回值有时是字符串,有时是{ value: '...' }。枚举结果直接split可能在失败时拿到 undefined。后来加了两个小封装,统一先取出有效字符串;只要内容里带#就当错误。
读身份用的是同步请求。枚举、读证书会卡一下主线程。单 Key 自动登录放在 mounted 里还能接受,以后 Key 更多可能得加全屏 loading,或者跟厂商要异步接口(我们封装里其实留过 axios 方案的注释,没启用)。
联调只能真机。开发环境可以配默认账号密码,但 UKey 那条线必须本机装控件、插实体 Key。验收就列几条:没插 Key、只插一把、插两把、PIN 错、一证多用户、关掉 UKey 开关。
自测可以这么过一遍
- 没插 Key 或枚举失败 → 有提示,页面不崩
- 只插第一把 → 自动进,没有 PIN 框
- 两把都插 → 能选 Key;选第一把不要 PIN;选第二把必须 PIN
- 第二把 PIN 错 → 本地服务报
#开头错误,别拿脏数据去调登录 - 一个证书对应多个系统用户 → 出列表,选完能进
- 后台关掉 UKey 登录 → 只剩账号密码
写在最后
双 Key 难的不是多写一个下拉框,而是:枚举结果要映射到不同的合规策略(免 PIN / 要 PIN),并且单 Key 路径尽量别动。我们做法是入口分流、出口合并——前面按设备数分支,后面登录结果只维护一处。
如果你也在做 Web + UKey,建议先把本机服务的「枚举格式、错误码长什么样、后端一个身份几个用户」跟厂商和后端对齐,这样处理起来就会清爽很多。
