当前位置: 首页 > news >正文

微信小程序人脸认证1.0迁移2.0

最近老是收到微信平台的通知信息,告知“原微信人脸核身接口将于2026年6月30日停止服务,逾期未切换将无法使用人脸核身功能。”,看了一下官网的文档,2.0的使用变得更复杂了,所以整理了一下需要使用到的接口和流程,文中代码仅展示核心逻辑和框架,需根据实际项目调整。

概览

2.0 接口共需要使用以下四个接口:

名称 作用 文档 前后端
getAccessToken 获取接口调用凭据 官网 后端
getVerifyId 获取用户人脸核身会话唯一标识 官网 后端
wx.requestFacialVerify 发起人脸验证 官网 前端
queryVerifyInfo 查询人脸认证结果 官网 后端

调用流程

  1. 后端获取 AppId、AppSecret
  2. 后端用 AppId、AppSecret 调用 getAccessToken 获取 AccessToken
  3. 后端用 AccessToken 调用 getVerifyId 获取 verifyId,并持久化 out_seq_no、openid、cert_info 与 verifyId 的映射
  4. 后端将 verifyId 返回给前端,前端调用 wx.requestFacialVerify 发起人脸认证(需在 1 小时内完成)
  5. 前端认证完成后通知后端,后端用 verifyId 查出关联数据,调用 queryVerifyInfo 查询真实结果

时序图

sequenceDiagramparticipant 小程序前端participant 业务后端participant 微信后台小程序前端->>业务后端: 1. 传递用户实名信息(姓名、身份证)业务后端->>微信后台: 2. 调用 getAccessToken(携带 appid、secret)微信后台-->>业务后端: 3. 返回 access_token业务后端->>微信后台: 4. 调用 getVerifyId(携带 access_token、实名信息)微信后台-->>业务后端: 5. 返回 verify_id业务后端-->>业务后端: 6. 持久化 verifyId → (out_seq_no, openid, cert_info) 映射业务后端-->>小程序前端: 7. 返回 verify_id小程序前端->>小程序前端: 8. 调用 wx.requestFacialVerify({verify_id})微信后台-->>小程序前端: 9. 返回人脸核身前端结果小程序前端->>业务后端: 10. 通知后端验证已完成(携带 verify_id)业务后端->>业务后端: 11. 根据 verifyId 查出 out_seq_no、openid、cert_info业务后端->>微信后台: 12. 调用 queryVerifyInfo(携带 verify_id 等参数)微信后台-->>业务后端: 13. 返回最终核验结果业务后端-->>小程序前端: 14. 返回最终结果,前端决定后续业务

后端接口清单

后端至少需要提供两个接口给前端:

  • 获取 verifyId
  • 查询真实认证结果

获取 AppId、AppSecret

官方文档

在微信公众平台 → 开发与服务 → 开发管理页面中获取:

  • AppID:固定值,直接复制
  • AppSecret:需要手动生成

⚠️ 如果 AppID 或 AppSecret 不慎泄露,立即重置 AppSecret。重置后旧的 AppSecret 无法使用,所有使用到的业务系统都需要更换。

调用 getAccessToken 接口

官方文档

请求信息

  • 请求方式:GET
  • 接口地址https://api.weixin.qq.com/cgi-bin/token

请求参数

参数 类型 必填 说明 来源
appid string 小程序唯一凭证,即 AppID 获取 AppId、AppSecret
secret string 小程序唯一凭证密钥,即 AppSecret 获取 AppId、AppSecret
grant_type string 固定值 client_credential 固定值

返回参数

参数 类型 说明
access_token string 获取到的凭证
expires_in number 凭证有效时间,单位秒。目前为 7200 秒(2 小时)

返回示例:

{"access_token": "ACCESS_TOKEN","expires_in": 7200
}

💡 普通 token:2 小时有效,过期前需提前刷新,建议本地缓存并提前 5 分钟刷新避免边界失效。
💡 稳定版 token:长期有效,推荐生产环境使用。详见 获取稳定版接口调用凭据。

示例代码

核心逻辑:拼接 URL 请求微信接口,解析返回的 access_token 并缓存。

public String getAccessToken() throws Exception {String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",appId, appSecret);// 发送 GET 请求,解析 JSON 返回 access_token// 建议本地缓存,提前 5 分钟刷新,避免边界过期// access_token 过期时需自动刷新重试
}

调用 getVerifyId 接口

官方文档

请求信息

  • 请求方式:POST
  • 接口地址https://api.weixin.qq.com/cityservice/face/identify/getverifyid?access_token=TOKEN

请求参数

URL 参数:

参数 类型 必填 说明 来源
access_token string 接口调用凭证 getAccessToken 返回

请求体参数:

参数 类型 必填 说明 来源
out_seq_no string 业务侧唯一标识(一个 AppID 下唯一),5-32 字符,只能包含数字、大小写字母、_- 业务侧生成
openid string 用户身份标识,用户登录小程序后获取,详见 code2session 小程序登录获取
cert_info object 用户身份信息,见下表 前端传入

cert_info 对象:

参数 类型 必填 说明 来源
cert_type string 证件类型,身份证固定为 IDENTITY_CARD 固定值
cert_name string 姓名 前端传入
cert_no string 身份证号 前端传入

请求示例:

{"out_seq_no": "550e8400e29b41d4a716446655440000","openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M","cert_info": {"cert_type": "IDENTITY_CARD","cert_name": "张三","cert_no": "110101199001011234"}
}

⚠️ out_seq_no 要求 5-32 字符,UUID.randomUUID().toString() 生成的是 36 字符(含横杠),超出限制会导致接口返回 84011 out_seq_no 格式无效。应去掉横杠(32 字符)或使用时间戳+随机数生成。

返回参数

参数 类型 说明
errcode number 错误码,0 表示成功
errmsg string 错误信息
verify_id string 人脸核身会话唯一标识
expires_in number verify_id 有效时间,单位秒,默认 3600(1 小时)

返回示例:

{"errcode": 0,"errmsg": "ok","verify_id": "verify_id_xxxx","expires_in": 3600
}

⚠️ verify_id 有效期为 1 小时,前端获取后应尽快调起人脸认证,超时后需重新获取。

示例代码

核心逻辑:生成 out_seq_no,携带 access_token 和实名信息 POST 请求,返回 verify_id。成功后需持久化 out_seq_no、openid、cert_info 与 verify_id 的映射关系,供 queryVerifyInfo 使用。

public String getVerifyId(String openid, String certName, String certNo) throws Exception {String accessToken = getAccessToken();String url = "https://api.weixin.qq.com/cityservice/face/identify/getverifyid?access_token=" + accessToken;// out_seq_no 要求 5-32 字符,UUID 去横杠刚好 32 字符String outSeqNo = UUID.randomUUID().toString().replaceAll("-", "");String body = objectMapper.writeValueAsString(Map.of("out_seq_no", outSeqNo,"openid", openid,"cert_info", Map.of("cert_type", "IDENTITY_CARD","cert_name", certName,"cert_no", certNo)));// POST 请求,解析返回的 verify_id// 需要根据 errcode 做错误分类处理(如 access_token 过期自动刷新重试)// 成功后持久化映射关系,供 queryVerifyInfo 使用// redis.set("FACE:VERIFY:" + verifyId, {outSeqNo, openid, certName, certNo}, 3600s);
}

发起人脸认证

官方文档

此步骤在小程序前端完成,需要先从后端获取到 verifyId。

请求信息

调用方法:

wx.requestFacialVerify(Object object)

参数说明

参数 类型 必填 说明 来源
verifyId string 人脸核身会话唯一标识 getVerifyId 返回
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(成功/失败都会执行)

⚠️ success 回调仅代表前端拉起人脸认证成功,不代表人脸验证通过。需要在 success 中通知后端调用 queryVerifyInfo 查询真实结果。

示例代码

前端完整调用流程:先请求后端获取 verifyId → 调起人脸认证 → 成功后通知后端查询结果。

// 1. 请求后端获取 verifyId
wx.request({url: 'https://your-server.com/api/face/get-verify-id',method: 'POST',data: { openid, certName, certNo },success(res) {// 2. 调起人脸认证(verifyId 有效期 1 小时,获取后尽快调起)wx.requestFacialVerify({verifyId: res.data.verifyId,success() {// 3. 认证成功,通知后端查询真实结果(后端根据 verifyId 查出完整参数)wx.request({url: 'https://your-server.com/api/face/query-result',method: 'POST',data: { verifyId: res.data.verifyId },success(result) {if (result.data.verifyRet === 10000) {console.log('认证成功');}}});},fail() {console.log('人脸认证失败');}});}
});

调用 queryVerifyInfo 接口

官方文档

请求信息

  • 请求方式:POST
  • 接口地址https://api.weixin.qq.com/cityservice/face/identify/queryverifyinfo?access_token=TOKEN

请求参数

URL 参数:

参数 类型 必填 说明 来源
access_token string 接口调用凭证 getAccessToken 返回

请求体参数:

参数 类型 必填 说明 来源
verify_id string 人脸核身会话唯一标识 getVerifyId 返回
out_seq_no string 业务侧唯一标识,必须与 getVerifyId 传入的一致 getVerifyId 时持久化的 out_seq_no
openid string 用户身份标识,必须与 getVerifyId 传入的一致 getVerifyId 时持久化的 openid
cert_hash string 证件信息摘要,需手动计算(计算规则见下方) 由持久化的 cert_info 计算得出

cert_hash 计算规则

cert_info 中的 cert_typecert_namecert_no 分别进行 Base64 编码(中文需先 UTF-8 编码),然后按顺序拼接:

cert_type=BASE64(cert_type)&cert_name=BASE64(cert_name)&cert_no=BASE64(cert_no)

对拼接结果进行 SHA-256 哈希,输出十六进制小写字符串。

返回参数

参数 类型 说明
errcode number 错误码,0 表示成功
errmsg string 错误信息
verify_ret number 验证结果,10000 表示识别成功

⚠️ 核身通过的判断条件:errcode = 0verify_ret = 10000。微信后台会校验 cert_infoopenid,不一致则返回对应 errcode 而非 verify_ret,防止身份信息被篡改。

示例代码

核心逻辑:后端根据 verifyId 从缓存查出 out_seq_no、openid、cert_info,计算 cert_hash 后调用微信接口,判断 verify_ret 是否为 10000。

public int queryVerifyInfo(String verifyId) throws Exception {// 从缓存取出 getVerifyId 时持久化的关联数据Map<String, String> record = redis.get("FACE:VERIFY:" + verifyId);String outSeqNo = record.get("out_seq_no");String openid = record.get("openid");String certName = record.get("cert_name");String certNo = record.get("cert_no");String accessToken = getAccessToken();String url = "https://api.weixin.qq.com/cityservice/face/identify/queryverifyinfo?access_token=" + accessToken;// 根据 cert_type(固定IDENTITY_CARD)、cert_name、cert_no 计算 cert_hashString certHash = computeCertHash(certName, certNo);String body = objectMapper.writeValueAsString(Map.of("verify_id", verifyId,"out_seq_no", outSeqNo,"openid", openid,"cert_hash", certHash));// POST 请求,解析返回的 verify_ret,10000 表示认证成功// 需要根据 errcode 做错误分类处理
}// cert_type 固定为 IDENTITY_CARD,cert_name 和 cert_no 为用户实际信息
private String computeCertHash(String certName, String certNo) throws Exception {String raw = "cert_type=" + Base64.getEncoder().encodeToString("IDENTITY_CARD".getBytes(StandardCharsets.UTF_8))+ "&cert_name=" + Base64.getEncoder().encodeToString(certName.getBytes(StandardCharsets.UTF_8))+ "&cert_no=" + Base64.getEncoder().encodeToString(certNo.getBytes(StandardCharsets.UTF_8));byte[] hash = MessageDigest.getInstance("SHA-256").digest(raw.getBytes(StandardCharsets.UTF_8));StringBuilder hex = new StringBuilder();for (byte b : hash) hex.append(String.format("%02x", b));return hex.toString();
}

总结

完整的认证流程:

  1. 后端保存 AppId、AppSecret
  2. 后端用 AppId、AppSecret 获取 AccessToken(建议缓存,2 小时有效期;生产环境推荐使用稳定版 token)
  3. 前端传递用户实名信息给后端,后端调用 getVerifyId 获取 verifyId,并持久化 out_seq_no、openid、cert_info 与 verifyId 的映射
  4. 后端将 verifyId 返回给前端(verifyId 有效期 1 小时,前端需尽快调起认证)
  5. 前端调用 wx.requestFacialVerify 发起人脸认证
  6. 前端认证成功后通知后端(仅传 verifyId 即可)
  7. 后端根据 verifyId 从缓存查出完整参数,调用 queryVerifyInfo 查询真实结果并返回给前端

后端需要提供的接口:

  • POST /api/face/get-verify-id — 返回 verifyId
  • POST /api/face/query-result — 前端仅传 verifyId,后端自行查缓存补齐参数后查询真实结果
http://www.jsqmd.com/news/877327/

相关文章:

  • 2026推荐:佳木斯CMA甲醛检测治理及公共卫生检测报告地址联系方式集合(2026版) - 金诚回收
  • 告别模组管理混乱:5个核心功能让《博德之门3》模组管理变得简单
  • 终极指南:如何用GHelper手动风扇控制告别ROG笔记本噪音与高温困扰?
  • 脚本报错看不懂?让 AI 充当你的私人自动化测试答疑导师
  • BinderTool:解密FromSoftware游戏资源的专业工具
  • SISSO算法驱动Y型六角铁氧体室温磁电性能突破
  • 用 AI 辅助梳理混乱的旧系统架构:基于代码仓生成业务调用拓扑图
  • 终极指南:5步解锁Zotero-GPT智能文献助手,让AI成为你的研究伙伴
  • 2026推荐:菏泽母婴除甲醛CMA甲醛检测治理公司推荐品牌排行榜 - 金诚回收
  • 2026推荐:龙岩母婴除甲醛CMA甲醛检测治理公司推荐品牌排行榜 - 金诚回收
  • 2026推荐:佳木斯CMA甲醛检测治理及公共卫生检测报告排行榜(2026版) - 金诚回收
  • 计算论证与机器学习融合:从黑箱到透明决策的工程实践
  • 基于双机器学习与柯西-施瓦茨不等式的数据融合边界估计
  • DLSS Swapper:5步轻松管理游戏DLSS版本,让帧率飙升不是梦
  • 3大核心功能+70+精选MOD:HS2-HF Patch如何让HoneySelect2新手变高手
  • 2026推荐:贺州CMA甲醛检测治理及公共卫生检测报告地址联系方式集合(2026版) - 金诚回收
  • 还在手写 XPath?AI 视觉自动化将如何终结 Selenium 时代
  • 2026推荐:嘉兴CMA甲醛检测治理公司及洁净室公共卫生检测报告排行榜(2026版) - 金诚回收
  • 2026推荐:娄底CMA甲醛检测治理及公共卫生检测报告排行榜(2026版) - 金诚回收
  • 提效篇总结:如何将上述 AI 技巧固化到你的日常测试 SOP 中?
  • 2026推荐:嘉兴CMA甲醛检测治理及公共卫生检测报告地址联系方式集合(2026版) - 金诚回收
  • 2026推荐:娄底母婴除甲醛CMA甲醛检测治理公司多少钱怎么收费 - 金诚回收
  • 咸阳卫生间漏水到楼下,外墙渗漏起皮,楼顶下雨滴水,专业防水补漏公司帮您解决问题。本地权威防水补漏TOP5强烈推荐(2026全新房屋修缮维修指南) - 企业资讯
  • 机器学习开源社区贡献者行为画像:四类角色解析与社区治理启示
  • 2026推荐:鹤壁CMA甲醛检测治理及公共卫生检测报告地址联系方式集合(2026版) - 金诚回收
  • 对比直接使用官方API,Taotoken在账单管理与成本控制上的优势
  • 2026推荐:鹤壁CMA甲醛检测治理及公共卫生检测报告排行榜(2026版) - 金诚回收
  • FFmpegGUI:让专业视频处理变得像聊天一样简单 [特殊字符]
  • 2026推荐:嘉兴母婴除甲醛CMA甲醛检测治理公司哪家好权威机构 - 金诚回收
  • 2026年最新Java面试题(含场景)最全汇总:涵盖JVM/并发/分布式/微服务