dev.md 33.4 KB
Newer Older
JiaRongPing's avatar
JiaRongPing 已提交
1
## 开发指南
雪洛's avatar
雪洛 已提交
2

3 4
> uni实人认证相关功能建议或问题,可以加入uni-im交流群进行讨论,[点此加入](https://im.dcloud.net.cn/#/?joinGroup=6445fc67bc1254655dcbf5f7)

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
5 6 7
uni实人认证服务,分前端api和云端api,云端为uniCloud API。

如开发者的业务不在uniCloud上,需参考[云函数url化](../http.md)文档编写云函数提供http接口供外部访问,由uniCloud获取到认证结果后转交给开发者的非uniCloud服务器上。
雪洛's avatar
雪洛 已提交
8

雪洛's avatar
雪洛 已提交
9
首先在uniCloud服务空间新建一个云函数/云对象,用于处理实人认证业务。新建时在[云函数的扩展库](../cf-functions.md#extension)中配置uni-cloud-verify扩展库。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
10

11 12


DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
13 14
在uni-app客户端和uniCloud云函数中调用如下api,实现下图流程:

雪洛's avatar
雪洛 已提交
15 16
- 客户端获取metaInfo:[uni.getFacialRecognitionMetaInfo](#get-meta-info)
- 客户端调起sdk刷脸认证:[uni.startFacialRecognitionVerify()](#start-frv)
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
17 18 19 20
- 云函数获取实人认证实例:[uniCloud.getFacialRecognitionVerifyManager()](#get-frv-manager)
- 云函数提交姓名、身份证号以获取认证服务的certifyId:[frvManager.getCertifyId()](#get-certify-id)
- 云函数使用certifyId获取认证结果:[frvManager.getAuthResult()](#get-auth-result)

雪洛's avatar
雪洛 已提交
21
完整认证流程如下:
雪洛's avatar
雪洛 已提交
22 23 24 25

```mermaid
sequenceDiagram
  actor user as 用户端
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
26
  participant cf as 云函数/云对象
雪洛's avatar
雪洛 已提交
27 28
  participant service as 认证服务
  activate user
雪洛's avatar
雪洛 已提交
29 30 31 32 33 34 35 36 37 38 39
  user->>+user: 获取设备信息metaInfo
  user->>+cf: 提交姓名、身份证号、metaInfo获取certifyId
  cf->>+service: 提交姓名、身份证号、metaInfo获取certifyId
  service-->>-cf: 返回certifyId
  cf-->>-user: 返回certifyId
  user->>+service: 调用sdk进行刷脸认证
  service-->>-user: 返回认证结果
  user->>+cf: 请求校验认证结果
  cf->>+service: 请求认证结果
  service-->>-cf: 返回认证结果
  cf-->>-user: 返回最终实人认证结果
雪洛's avatar
雪洛 已提交
40 41 42
  deactivate user
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
43

雪洛's avatar
雪洛 已提交
44
- 如果您使用uni-id,那么uni-id-pages已经帮您内置好相关功能,前端页面和云端逻辑均已写好,安全、无需开发、拿来就用。[详见](/uniCloud/uni-id/summary.md#frv)
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
45
- 如果您的业务系统不在uniCloud上,那么需要在上述流程图中加一个原业务服务器,由云函数和原业务服务器进行token校验、传递认证结果。
雪洛's avatar
雪洛 已提交
46

雪洛's avatar
雪洛 已提交
47 48 49
### 接口防刷

由于实人认证涉及费用,为避免其他人盗刷您的余额,您应当谨慎编码,防止漏洞。一般可以通过一个用户每天限制实名次数来实现防刷,未登录用户禁止调用认证接口。如果有更高的安全需求可以使用uni安全网络,可以有效防止伪造客户端请求,[详见](../secure-network.md)
雪洛's avatar
雪洛 已提交
50

雪洛's avatar
雪洛 已提交
51 52
### 客户端接口

W
wanganxp 已提交
53 54
uni-app x的客户端API文档[另见](https://uniapp.dcloud.net.cn/uni-app-x/api/facial-recognition-verify.html)

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
55
#### 获取实人认证设备信息@get-meta-info
DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
56 57
调用刷脸前通过客户端先获取设备信息,调用[uni.getFacialRecognitionMetaInfo](https://uniapp.dcloud.net.cn/api/plugins/facialRecognitionVerify.html)  

雪洛's avatar
雪洛 已提交
58 59
`const metaInfo = uni.getFacialRecognitionMetaInfo();`

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
60 61 62 63 64 65
**返回值**

|字段名		|类型		| 描述		|
|:-:			|:-:		|:-:		|
|metaInfo|String	|云函数获取认证服务的certifyId时,在入参metaInfo中传入该值	|

雪洛's avatar
雪洛 已提交
66 67 68 69 70 71 72
#### 调起实人认证界面@start-frv

通过云函数获取certifyId后,在客户端调用[uni.startFacialRecognitionVerify](https://uniapp.dcloud.net.cn/api/plugins/facialRecognitionVerify.html)打开认证界面,通过刷脸操作获取认证结果。

`uni.startFacialRecognitionVerify(OBJECT)`


DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
73
**参数说明**  
雪洛's avatar
雪洛 已提交
74 75 76 77 78 79 80 81 82 83 84 85

| 参数						| 类型		| 是否必传	| 支持平台		| 描述															|
| ---						| ---		| ---		| ---			| ---															|
| certifyId					| String	| 是		| App			| 认证流水号,由服务端根据接入的业务模式调用对应的初始化接口获取		|
| progressBarColor			| String	| 否		| App			| 刷脸圈的颜色													|
| screenOrientation      | String  | 否    | App-Android  | 认证界面UI朝向。port 为竖屏,land 为横屏,默认为 port|
| success					| Function	| 否		| App			| 成功回调														|
| fail						| Function	| 否		| App			| 失败回调														|
| complete					| Function	| 否		| App			| 完成回调														|

注: 颜色字符串格式为“#RRGGBB”,RRGGBB为十六进制字符串,如红色("#FF0000")  

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
86
**返回值**
雪洛's avatar
雪洛 已提交
87

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
88 89 90 91 92 93
| 字段名		|  类型  | 描述				|
| ---			| --- | ---					|
| errSubject| String	| 模块名称(uni-facialRecognitionVerify)|
| errCode	|	Number| 错误码,详情见:[错误码](#err-code)|
| errMsg		| String | 错误信息,详情见:[错误码](#err-code)|
| cause		|	Object| SDK返回的原始数据 (certifyId不为空时返回)|
雪洛's avatar
雪洛 已提交
94

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
95
**cause**  
雪洛's avatar
雪洛 已提交
96

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| 字段名	|  类型 | 描述				|
| ---		| ---		| ---		|
| code	|	Number| SDK原始错误码		|
| message	| String | SDK原始错误信息		|

**示例代码**

```js
uni.startFacialRecognitionVerify({
    certifyId:"",
    progressBarColor: "#CC0000", //刷脸圈的颜色
    screenOrientation: "port", //认证界面UI朝向
    success:(e)=>{
        console.log(JSON.stringify(e))
    },
    fail:(e)=>{
        console.log(JSON.stringify(e))
    },
    complete:(e)=>{
        console.log(JSON.stringify(e))
    }
})
```
雪洛's avatar
雪洛 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

#### iOS平台自定义UI  
iOS平台不支持通过参数的方式修改刷脸页的提示文案,但可以通过自定义bundle文件的方式修改提示内容以及国际化信息

[APBToygerFacade.bundle文件下载](https://native-res.dcloud.net.cn/uni-app/file/APBToygerFacade.zip)

首先需要下载APBToygerFacade.bundle文件,可通过修改APBToygerFacade.bundle中的内容自定义多语言文案,如 zh-Hans.strings 代表中文文案,en.strings 代表英文文案,内容格式为 "APBToygerFacade:xxxA"="xxxB",xxxA 为目标修改文案,xxxB 为修改后的文案,示例内容如下:
```
"APBToygerFacade:xxxA"="xxxB";
"APBToygerFacade:当前设备不支持刷脸"="当前设备不支持刷脸";
"APBToygerFacade:拿起手机眨眨眼"="拿起手机,眨眨眼";
"APBToygerFacade:再试一次"="再试一次";
"APBToygerFacade:无法启动相机"="无法打开相机";
"APBToygerFacade:网络不给力"="网络异常";
```

此处文案修改后需要完整测试回归 UI 以及文案变化影响,以免影响用户体验。修改后的bundle文件配到项目根目录的 nativeResources -> ios -> Resources 路径下后打包即可,详情参照[iOS原生应用配置文件和资源](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-ios.html) 

DCloud-yyl's avatar
DCloud-yyl 已提交
138 139
**Android平台暂不支持自定义UI**  

雪洛's avatar
雪洛 已提交
140 141
### 云函数接口

雪洛's avatar
雪洛 已提交
142
实人认证相关接口由uni-cloud-verify扩展库提供,调用`uniCloud.getFacialRecognitionVerifyManager()`需云函数/云对象中加载对应的扩展库。[参考](../cf-functions.md#extension)
雪洛's avatar
雪洛 已提交
143

study夏羽's avatar
study夏羽 已提交
144
![依赖扩展库](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/unicloud-frv-edit-extension.jpg)
雪洛's avatar
雪洛 已提交
145

雪洛's avatar
雪洛 已提交
146 147 148 149 150
#### 获取实人认证实例@get-frv-manager

**接口形式**

```js
雪洛's avatar
雪洛 已提交
151
uniCloud.getFacialRecognitionVerifyManager(Object GetFacialRecognitionVerifyManagerOptions)
雪洛's avatar
雪洛 已提交
152 153 154 155
```

**参数说明**

雪洛's avatar
雪洛 已提交
156
**Object GetFacialRecognitionVerifyManagerOptions**
雪洛's avatar
雪洛 已提交
157

雪洛's avatar
雪洛 已提交
158 159 160 161
|属性			|类型		|必填	|默认值	|说明																										|
|:-:			|:-:		|:-:	|:-:		|:-:																										|
|requestId|String	|是		|-			|本次云函数请求的requestId															|
|appId		|String	|否		|-			|用于在url化等无法获取客户端信息的场景下传入客户端appId	|
雪洛's avatar
雪洛 已提交
162 163 164

**返回值**

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
165
此接口返回实人认证实例对象
雪洛's avatar
雪洛 已提交
166 167 168

**示例代码**

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
169
- 云函数
雪洛's avatar
雪洛 已提交
170 171 172 173 174 175 176 177 178

```js
exports.main = async (event, context) => {
  const frvManager = uniCloud.getFacialRecognitionVerifyManager({
    requestId: context.requestId
  })
};
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
179
- 云对象
雪洛's avatar
雪洛 已提交
180 181 182 183 184

```js
'use strict';
module.exports = {
  _before() {
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
185
    // 本示例写在_before中,可以按需调整到某个方法中
雪洛's avatar
雪洛 已提交
186 187 188 189 190 191 192 193 194 195 196 197
    this.frvManager = uniCloud.getFacialRecognitionVerifyManager({
      requestId: this.getUniCloudRequestId()
    })
  }
}
```

#### 获取certifyId@get-certify-id

**接口形式**

```js
雪洛's avatar
雪洛 已提交
198
frvManager.getCertifyId(Object GetCertifyIdOptions)
雪洛's avatar
雪洛 已提交
199 200 201 202
```

**参数说明**

雪洛's avatar
雪洛 已提交
203
**Object GetCertifyIdOptions**
雪洛's avatar
雪洛 已提交
204

雪洛's avatar
雪洛 已提交
205 206 207 208
|属性				|类型		|必填	|默认值	|说明													|
|:-:				|:-:		|:-:	|:-:		|:-:													|
|realName		|String	|是		|-			|用户真实姓名									|
|idCard			|String	|是		|-			|用户身份证号									|
雪洛's avatar
雪洛 已提交
209 210
|metaInfo		|String	|是		|-			|客户端获取设备信息返回的metaInfo	|
|needPicture|Boolean|否		|false	|是否需要采集用户照片					|
雪洛's avatar
雪洛 已提交
211
|model      |String |否		|false	|`HBuilderX 3.91及以上版本支持`要进行活体检测的类型:LIVENESS(默认):眨眼动作活体检测,PHOTINUS_LIVENESS:眨眼动作活体+炫彩活体双重检测,MULTI_ACTION:多动作活体检测。当前为眨眼+任意摇头检测					|
雪洛's avatar
雪洛 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229

**返回值**

|字段名		|类型		|必备	|说明																								|
|:-:			|:-:		|:-:	|:-:																								|
|certifyId|String	|是		|认证id,用于客户端调用认证接口及云函数获取认证结果	|

**示例代码**

云函数

```js
exports.main = async (event, context) => {
  const frvManager = uniCloud.getFacialRecognitionVerifyManager({
    requestId: context.requestId
  })
  const result = await frvManager.getCertifyId({
    realName: '张三',
雪洛's avatar
雪洛 已提交
230 231
    idCard: 'xxxxxx',
    metaInfo: '{"xx": "xx"}'
雪洛's avatar
雪洛 已提交
232 233 234 235 236 237 238 239 240
  })
  return result
};
```

云对象

```js
module.exports = {
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
241
  _before() { // _before是云对象中每个方法运行前都会执行的方法
雪洛's avatar
雪洛 已提交
242 243 244 245 246 247 248
    this.frvManager = uniCloud.getFacialRecognitionVerifyManager({
      requestId: this.getUniCloudRequestId()
    })
  },
  async getCertifyId() {
    const result = await this.frvManager.getCertifyId({
      realName: '张三',
雪洛's avatar
雪洛 已提交
249 250
      idCard: 'xxxxxx',
      metaInfo: '{"xx": "xx"}'
雪洛's avatar
雪洛 已提交
251 252 253 254 255 256 257 258 259 260 261
    })
    return result
  }
}
```

#### 获取认证结果@get-auth-result

**接口形式**

```js
雪洛's avatar
雪洛 已提交
262
frvManager.getAuthResult(Object GetAuthResultOptions)
雪洛's avatar
雪洛 已提交
263 264 265 266
```

**参数说明**

雪洛's avatar
雪洛 已提交
267
**Object GetAuthResultOptions**
雪洛's avatar
雪洛 已提交
268 269

|属性			|类型	|必填	|默认值	|说明																		|
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
270 271
|:-:			|:-:	|:-:	|:-:	|:-:																		|
|certifyId		|String	|是		|-		|认证id																		|
雪洛's avatar
雪洛 已提交
272 273 274

**返回值**

雪洛's avatar
雪洛 已提交
275 276 277 278 279 280
|字段名			|类型		|必备											|说明																																								|
|:-:				|:-:		|:-:											|:-:																																								|
|authState	|String	|是												|人脸检测状态。SUCCESS:检测成功;FAIL:检测失败								|
|score			|Number	|authState为SUCCESS时必备	|活体检测结果分数																																		|
|quality		|Number	|authState为SUCCESS时必备	|人脸图片质量分																																			|
|pictureUrl	|String	|authState为SUCCESS时必备	|实人认证采集的图片链接,此链接为临时链接请勿直接保存到数据库,应下载后自行保存文件	|
雪洛's avatar
雪洛 已提交
281

JiaRongPing's avatar
JiaRongPing 已提交
282 283
::: warning 注意
- 获取 `certifyId` 后,仅在`24`小时内可正常调用`getAuthResult`接口获取认证结果,超过`24`小时后请求该接口将返回`56001 请求记录已过期`错误。
JiaRongPing's avatar
JiaRongPing 已提交
284
- `certifyId` 成功调用后,无论认证结果是否匹配,都仅可再调用`5``getAuthResult`接口获取认证结果,超过`5`次后请求该接口将返回`56002 请求次数已超限`错误。
JiaRongPing's avatar
JiaRongPing 已提交
285 286 287
- `pictureUrl` 照片地址有效期为`15`分钟,从查询时开始计时,如有存储需求请尽快处理。
:::

雪洛's avatar
雪洛 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
**示例代码**

云函数

```js
exports.main = async (event, context) => {
  const frvManager = uniCloud.getFacialRecognitionVerifyManager({
    requestId: context.requestId
  })
  const result = await frvManager.getAuthResult({
    certifyId: 'xxxxxx'
  })
  return result
};
```

云对象

```js
module.exports = {
  _before() {
    this.frvManager = uniCloud.getFacialRecognitionVerifyManager({
      requestId: this.getUniCloudRequestId()
    })
  },
  async getAuthResult() {
    const result = await this.frvManager.getAuthResult({
      certifyId: 'xxxxxx'
    })
    return result
  }
}
```

#### 错误处理

雪洛's avatar
雪洛 已提交
324
可以通过try catch捕获接口抛出的错误,接口抛出的错误为标准的[uni错误对象](../../tutorial/err-spec.md)
雪洛's avatar
雪洛 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356

具体错误码规范见:[错误码](#err-code)

**示例**

```js
module.exports = {
  _before() {
    this.frvManager = uniCloud.getFacialRecognitionVerifyManager({
      requestId: this.getUniCloudRequestId()
    })
  },
  async getAuthResult() {
    try {
      const result = await this.frvManager.getAuthResult({
        certifyId: 'xxxxxx'
      })
      return result
    } catch (e) {
      if(e.errCode === 50001 || e.errCode === 50002) {
        throw new Error('缺少参数或参数不正确')
      }
      throw e
    }
  }
}
```

### 错误码@err-code

**云端错误码**

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
357 358 359 360 361 362 363 364 365 366
|错误码	|说明													|
|:-:	|:-:													|
|0		|请求成功												|
|50001	|缺少参数												|
|50002	|参数类型、取值不正确									|
|54003	|appId不存在											|
|54004	|服务空间不在白名单中									|
|54020	|请求记录不存在,certifyId无效							|
|54021	|云函数内缺少接口调用凭证,请联系DCloud处理				|
|54022	|服务空间不存在											|
JiaRongPing's avatar
JiaRongPing 已提交
367
|54100	|实人认证账号余额不足									|
JiaRongPing's avatar
JiaRongPing 已提交
368
|54101	|费用获取失败,请联系DCloud处理							|
JiaRongPing's avatar
JiaRongPing 已提交
369
|54102	|金额冻结失败,请联系DCloud处理							|
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
370
|55000	|服务器错误,请联系DCloud处理							|
雪洛's avatar
雪洛 已提交
371
|55001	|Api调用失败,实人认证服务商服务不可用,请联系DCloud处理|
JiaRongPing's avatar
JiaRongPing 已提交
372
|55023	|尚未开通实人认证										|
JiaRongPing's avatar
JiaRongPing 已提交
373 374
|56001	|请求记录已过期											|
|56002	|请求次数已超限											|
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
375
|60000	|服务不可用,请联系DCloud处理							|
雪洛's avatar
雪洛 已提交
376 377 378

**客户端错误码**

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
379 380 381 382 383 384 385 386 387 388 389
|错误码	|错误信息			|描述											|
|---	|---				|---											|
|0		|刷脸完成			|实际结果需要通过服务端查询接口					|
|10001	|certifyId不能为空	|参数certifyId为空								|
|10010	|刷脸异常			|刷脸异常,具体原因详见cause						|
|10011	|验证中断			|如用户主动退出、验证超时等,具体原因详见cause	|
|10012	|网络异常			|网络异常										|
|10013	|刷脸验证失败		|实际结果需要通过服务端查询结果					|
|10020	|设备设置时间异常	|设备设置时间异常,仅iOS返回					|


DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
390
### 注意事项 
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
391

DCloud_iOS_WZT's avatar
DCloud_iOS_WZT 已提交
392 393 394 395
- 为对抗攻击,实人认证SDK返回的错误原因比较模糊。  
- HBuilderX3.7.4+新增支持,标准基座可直接真机运行,打包或自定义基座需在“App模块配置”中勾选“FacialRecognitionVerify(实人认证)”(注意不是faceId)参考[详情](https://uniapp.dcloud.net.cn/tutorial/app-facialRecognitionVerify.html)
- App-Android平台要求**Android5**(API Leavel 21)及以上系统,App-iOS平台要求**iOS9**及以上系统
- App端使用实人认证SDK,需在隐私政策的三方SDK中添加实人认证功能描述,参考[详情](https://ask.dcloud.net.cn/article/39484#FacialRecognitionVerify)
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
396 397


C
chenruilong 已提交
398 399 400
### 非 uniCloud 业务使用@uni-frv-external

> HBuilderX 版本需大于3.7.6
C
chenruilong 已提交
401 402
> 
> 非uniCloud的传统服务器,可通过本插件方便调用uni实人认证
C
chenruilong 已提交
403

C
chenruilong 已提交
404
如果您的业务没有部署在 uniCloud 上,可以通过 uni-frv-external 来实现实人认证功能。
C
chenruilong 已提交
405
uni-frv-external 集成了实名认证前端组件和云端云对象,适用于没有使用uniCloud或没有使用uni-id账号体系的项目。
C
chenruilong 已提交
406

C
chenruilong 已提交
407 408
如果您的业务使用uniCloud开发,不推荐使用此插件,可以通过实人认证[云函数接口](#get-frv-manager)调用或者使用[uni-id-pages](https://ext.dcloud.net.cn/plugin?id=8577)插件,[uni-id-pages](https://ext.dcloud.net.cn/plugin?id=8577)内同样集成了实名认证前端组件和云端云对象。

C
chenruilong 已提交
409
插件下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-frv-external](https://ext.dcloud.net.cn/plugin?name=uni-frv-external)
C
chenruilong 已提交
410 411 412 413 414 415 416 417 418

#### 业务流程

```mermaid
sequenceDiagram
  actor client as 客户端
  participant cf as 开发者云函数
  participant dev as 开发者服务器
  participant service as 实人认证服务
C
chenruilong 已提交
419 420
  client->>+dev: 请求certifyId
  dev->>+cf: 携带用户信息请求certifyId (getCertifyId)
C
chenruilong 已提交
421 422
  cf->>+service: 请求certifyId
  service-->>-cf: 返回certifyId
C
chenruilong 已提交
423 424
  cf-->>-dev: 返回certifyId
  dev-->>-client: 返回certifyId
C
chenruilong 已提交
425 426
  client->>+service: 进行实人认证
  service-->-client: 返回认证结果
C
chenruilong 已提交
427 428
  client->>+dev: 请求绑定实名信息
  dev->>+cf: 请求认证结果 (getAuthResult)
C
chenruilong 已提交
429 430
  cf->>+service: 请求认证结果
  service-->>-cf: 返回认证结果
C
chenruilong 已提交
431 432
  cf->>-dev: 返回用户实名信息
  dev-->>-client: 返回绑定成功或失败
C
chenruilong 已提交
433 434 435 436 437
```

#### 项目文件说明
```text
├── uni_modules                                     存放[uni_module](/uni_modules)规范的插件。
C
chenruilong 已提交
438
│    ├── uni-frv-external                              
C
chenruilong 已提交
439 440 441 442 443
│    │   ├── changelog.md
│    │   ├── common                                     页面公共逻辑
│    │   │   ├── check-id-card.js                       校验身份证号合法性
│    │   │   └── common.scss
│    │   ├── components                                 公共组件
C
chenruilong 已提交
444
│    │   │   └── uni-frv-external-realname                 实名认证组件
C
chenruilong 已提交
445
│    │   │       ├── face-verify-icon.svg               实名认证错误提示Icon
C
chenruilong 已提交
446
│    │   │       └── uni-frv-external-realname.vue     
C
chenruilong 已提交
447 448 449 450 451 452 453 454 455
│    │   ├── package.json                               包管理文件
│    │   ├── pages                                  
│    │   │   └── common
│    │   │       └── webview                            用于实现应用内浏览或打开《用户协议和隐私协议》URL链接页面
│    │   │           └── webview.vue
│    │   ├── pages_init.json                            页面初始化文件
│    │   ├── readme.md
│    │   └── uniCloud
│    │       ├── cloudfunctions
C
chenruilong 已提交
456
│    │       │   └── uni-frv-external-co                实名认证云对象
C
chenruilong 已提交
457
│    │       │       ├── config.js                      加载uni-config-center/uni-frv-external-co/config.json配置文件
C
chenruilong 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
│    │       │       ├── functions                      云对象方法目录
│    │       │       │   ├── _after.js                  云对象加载后方法
│    │       │       │   ├── _before.js                 云对象执行前方法
│    │       │       │   ├── getAuthResult.js           获取实人认证结果
│    │       │       │   ├── getCertifyId.js            获取实人认证认证ID
│    │       │       │   └── index.js                   导出云对象方法文件
│    │       │       ├── index.obj.js                   云对象入口
│    │       │       ├── lang                           国际化目录
│    │       │       │   ├── en.js
│    │       │       │   ├── index.js
│    │       │       │   └── zh-hans.js
│    │       │       ├── lib                            云对象公共类库
│    │       │       │   ├── constants.js               变量定义声明文件
│    │       │       │   ├── error.js                   错误码
│    │       │       │   ├── sensitive-aes-cipher.js    敏感信息加解密
│    │       │       │   ├── utils.js                   工具类方法
│    │       │       │   └── validator.js               请求参数校验
│    │       │       └── package.json                   包管理文件
│    │       └── database                               数据库目录
│    │           └── opendb-frv-logs.schema.json        实人认证记录表
```

C
chenruilong 已提交
480 481 482 483
#### 开通与使用

1. 使用开发者账号登录[uniCloud控制台](https://unicloud.dcloud.net.cn/) ,选择`实人认证`栏目。在使用此功能前需要完成实名认证,可前往[开发者中心](https://dev.dcloud.net.cn/)完成实名认证。

study夏羽's avatar
study夏羽 已提交
484
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rpa1674035425.png)
C
chenruilong 已提交
485

C
chenruilong 已提交
486
2. 完成实名认证后,阅读uni实人认证服务协议并点击协议下方的“同意协议并开通”按钮,便可开通实人认证服务。
C
chenruilong 已提交
487

study夏羽's avatar
study夏羽 已提交
488
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rpa1674039403.png)
C
chenruilong 已提交
489 490 491

3. 实人认证为预付费业务,使用实人认证服务之前,需要先进行充值。点击页面上的“充值”按钮,并输入充值金额进行充值,充值金额最小为1元。

study夏羽's avatar
study夏羽 已提交
492
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rpa1674040001.png)
C
chenruilong 已提交
493

C
chenruilong 已提交
494
4. 在插件市场中导入[uni-frv-external](https://ext.dcloud.net.cn/plugin?name=uni-frv-external)至项目中。
C
chenruilong 已提交
495
5. 按需配置实名认证,具体配置[详见](#uni-frv-co-config), 实名认证配置文件路径:`uniCloud/cloudfunctions/common/uni-config-center/uni-frv-external-co/config.json`
C
chenruilong 已提交
496 497 498
7. 需要自行准备一个实名认证页面,引入`uni-frv-external-realname`组件,组件详细配置参考[前端使用](#uni-frv-external-feuse)
8.`manifest.json`中找到`App模块设置-打包模块设置`,勾选”实人认证“。

study夏羽's avatar
study夏羽 已提交
499
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/202302231806176.png)
C
chenruilong 已提交
500 501 502 503


9. 建议在 uniCloud 中配置服务空间白名单安全配置,可以提高接口调用安全性,防止被他人盗用。可点击“添加服务空间”按钮,选择相应的服务空间完成添加服务空间白名单,服务空间添加成功后,只有列表中的服务空间才可以调用当前账号下的实人认证接口。此列表为空时,不校验调用方的服务空间。

study夏羽's avatar
study夏羽 已提交
504
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rap1674040168.png)
C
chenruilong 已提交
505 506 507

10. 运行iOS/Android标准基座即可测试实名认证功能。

study夏羽's avatar
study夏羽 已提交
508
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/202302231812402.png)
C
chenruilong 已提交
509 510 511

11. 在用户完成实名认证后,可以在uniCloud控制台查看实人认证调用记录与统计。

study夏羽's avatar
study夏羽 已提交
512
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rpa1674040923.png)
C
chenruilong 已提交
513 514 515

但此业务数据量较大,为了维持服务的稳定性,只能查看30天内的某1天的全部调用记录,默认选择当天。

study夏羽's avatar
study夏羽 已提交
516
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/rpa/rpa1674041037.png)
C
chenruilong 已提交
517 518 519 520 521

系统可查看实人认证每日调用汇总数据,包括每日请求次数、每日请求成功次数、每日计费金额等汇总数据。

#### 配置(uni-frv-co)@uni-frv-co-config

C
chenruilong 已提交
522
实人认证配置文件路径:`uniCloud/cloudfunctions/common/uni-config-center/uni-frv-external-co/config.json`
C
chenruilong 已提交
523 524 525 526

```json
// 如果拷贝此内容切记去除注释
{
C
chenruilong 已提交
527
    "sensitiveInfoEncryptSecret": "", // 敏感信息加密密钥(长度为32位字符串),敏感信息如:姓名、身份证号、认证照片
C
chenruilong 已提交
528
	"realNameCertifyLimit": 5, // 限制每个用户每天实人认证次数
C
chenruilong 已提交
529
	"needAlivePhoto": true // 是否需要返回用户人脸照片
C
chenruilong 已提交
530 531 532
}
```

C
chenruilong 已提交
533
#### 前端使用@uni-frv-external-feuse
C
chenruilong 已提交
534

C
chenruilong 已提交
535
`uni-frv-external`插件导入至项目中,由于`uni-frv-external`提供的实名认证入口是组件形式,需要自行准备实名认证页面,将`uni-frv-external-realname`引入至页面中。
C
chenruilong 已提交
536 537 538 539

**组件用法**

```vue
C
chenruilong 已提交
540
<uni-frv-external-realname :agreement="{url: '', title: ''}" @start="startFunction" @result="resultFunction"></uni-frv-external-realname>
C
chenruilong 已提交
541 542 543 544 545 546 547 548 549 550
```

**组件Props**

| 属性名       | 类型     | 默认值 | 说明                |
|-----------|--------|-----|-------------------|
| agreement | Object | -   | 隐私协议展示名称与地址,默认不展示 |

**组件Event**

C
chenruilong 已提交
551 552 553 554
| 事件名称   | 事件说明 | 返回参数         |
|--------|--|--------------|
| start  | 开始认证事件 | 见下方Start说明  |
| finish | 刷脸完成事件 | 见下方Finish说明  |
C
chenruilong 已提交
555

C
chenruilong 已提交
556 557
Start 说明
> 以下是start事件的返回值,用于开发者向业务服务器获取certifyId时使用。获取后调起人脸识别界面。
C
chenruilong 已提交
558

C
chenruilong 已提交
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
| 参数       | 类型     | 说明                   |
|----------|--------|----------------------|
| metaInfo | string | 客户端获取设备信息返回的metaInfo |
| idCard   | string | 用户身份证号码              |
| realName | string | 用户真实姓名               |

Finish 说明
> 以下是finish事件的返回值,用于开发者向业务服务器查询认证结果。

| 参数        | 类型     | 说明      |
|-----------|--------|---------|
| certifyId | number | 认证Id    |
| idCard    | string | 用户身份证号码 |
| realName  | string | 用户真实姓名  |

**startFacialRecognitionVerify(certifyId: string)方法说明**

在 start 事件中获取到 certifyId 之后,通过 startFacialRecognitionVerify 方法调起人脸识别界面。
详细使用方式,参考下方示例。
C
chenruilong 已提交
578 579 580 581 582

**实名认证页面示例**

```vue
<template>
C
chenruilong 已提交
583 584 585 586 587 588 589 590 591 592 593
  <view class="content">
    <template v-if="isCertified">
      <uni-list>
        <uni-list-item class="item" title="姓名" :rightText="realName"></uni-list-item>
        <uni-list-item class="item" title="身份证号码" :rightText="idCard"></uni-list-item>
      </uni-list>
    </template>
    <template v-else>
      <uni-frv-external-realname ref="frv" :agreement="agreement" @start="startVerify" @finish="verifyFinish"></uni-frv-external-realname>
    </template>
  </view>
C
chenruilong 已提交
594 595 596
</template>

<script>
C
chenruilong 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
export default {
  data() {
    return {
      agreement: {
        title: "实名认证协议",
        url: "https://www.xxxxx.com"
      },
      isCertified: false,
      realName: '',
      idCard: ''
    }
  },
  methods: {
    async startVerify ({realName, idCard, metaInfo}) {
      uni.showLoading({ title: '加载中...' })
      uni.request({
        url: 'YOUR_BACKEND_API/getCertifyId',
        method: "POST",
        data: {
          realName,
          idCard,
          metaInfo
        },
        success: ({data}) => {
          if (data.errCode !== 0) {
            return uni.showModal({
              title: data.errCode,
              content: data.errMsg,
              showCancel: false
            })
          }
          if (data.certifyId) {
            this.$refs.frv.startFacialRecognitionVerify(data.certifyId)
          }
        },
        fail: (error) => {
          console.error(error.errMsg)
          uni.showModal({
            content: '请求异常,稍后再试',
            showCancel: false
          })
        },
        complete: () => {
          uni.hideLoading()
        }
      })
    },
    async verifyFinish (result) {
      uni.showLoading({ title: '加载中...' })
      uni.request({
        url: 'YOUR_BACKEND_API/getAuthResult',
        method: "POST",
        data: {
          certifyId: result.certifyId
        },
        success: ({data}) => {
          if (data.errCode !== 0) {
            return uni.showModal({
              title: data.errCode,
              content: data.errMsg,
              showCancel: false
            })
          }

          uni.showModal({
            content: "实名认证成功",
            showCancel: false,
            success: () => {
              this.isCertified = true
              this.realName = data.realName
              this.idCard = data.idCard
            }
          })
        },
        fail: (error) => {
          uni.showModal({
            content: '请求异常,稍后再试',
            showCancel: false
          })
          console.error(error.errMsg)
        },
        complete: () => {
          uni.hideLoading()
        }
      })
    },
  }
}
C
chenruilong 已提交
685
</script>
C
chenruilong 已提交
686 687 688 689 690

<style>

</style>

C
chenruilong 已提交
691 692
```

C
chenruilong 已提交
693 694 695 696 697 698 699 700 701 702 703 704 705
#### 开发者服务器调用说明@uni-frv-external-callback

uni-frv-external-co 只支持URL化方式访问,在调用之前需要在uniCloud控制台-云函数中设置 `uni-frv-external-co` 的URL路径。
为了保证URL化后的网络传输安全,内置了`uni-cloud-s2s` 公共模块的鉴权校验功能,对请求进行安全校验。

**请求结构**

| 请求相关项 | 说明                                    |
|-------|---------------------------------------|
| 请求协议	 | 云函数所有接口都使用 HTTPS,提高通信安全性              |
| 请求方式	 | 只支持 POST                              |
| 请求类型	 | application/json; charset=utf-8       |
| 校验方式  | 支持携带connectCode认证与使用签名认证,详见下方**鉴权说明** |
C
chenruilong 已提交
706

C
chenruilong 已提交
707
**鉴权说明**
C
chenruilong 已提交
708

C
chenruilong 已提交
709 710
`uni-frv-external`提供的接口,默认开启了鉴权验证,在调用接口前需要配置`uni-cloud-secure`
请求鉴权能力由 `uni-cloud-s2s` 公共模块提供,了解 `uni-cloud-s2s` [详见](/uniCloud/uni-cloud-s2s.md)
C
chenruilong 已提交
711

C
chenruilong 已提交
712
支持以下两种认证方式,根据业务需求选择不同的认证方式
C
chenruilong 已提交
713

雪洛's avatar
雪洛 已提交
714
1. 携带connectCode认证;相比签名认证,省去了复杂的签名计算过程。 调用简单,但安全性较低。[详见](/uniCloud/uni-cloud-s2s.md#code)
C
chenruilong 已提交
715
2. 使用签名认证;调用接口时需要使用签名密钥对请求内容进行签名计算,并将签名添加至请求头传输给云函数进行签名验证,相比简易鉴权方式,安全性高,可防止接口参数被篡改。[详见](/uniCloud/uni-cloud-s2s.md#sign)
C
chenruilong 已提交
716

C
chenruilong 已提交
717
如在您的业务也在uniCloud并且需要签名请求认证,可以使用`uni-cloud-s2s`提供的`getSecureHeaders`方法生成签名请求头 [详见](/uniCloud/uni-cloud-s2s.md#sign-method-of-server)
C
chenruilong 已提交
718

C
chenruilong 已提交
719
如果在uniCloud之外的场景中使用签名认证方式请求,参考[非云函数场景签名方法](/uniCloud/uni-cloud-s2s.md#sign-method-of-server)
C
chenruilong 已提交
720

C
chenruilong 已提交
721
**获取认证ID(getCertifyId)**
C
chenruilong 已提交
722

C
chenruilong 已提交
723 724 725 726
请求地址:
```
POST https://{云函数Url化域名}/{自定义路径}/getCertifyId
```
C
chenruilong 已提交
727

C
chenruilong 已提交
728
以下示例的请求地址均为示例,在实际使用中将更换为云函数URL化地址。
C
chenruilong 已提交
729 730 731

HTTP 示例
```javascript
C
chenruilong 已提交
732
POST /uni-frv-external-co/getCertifyId HTTP/1.1
C
chenruilong 已提交
733
Host: xxx.com
C
chenruilong 已提交
734 735
Unicloud-S2s-Timestamp: 1676882808550
Unicloud-S2s-Signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
C
chenruilong 已提交
736 737 738
Content-Type: application/json
Cache-Control: no-cache

C
chenruilong 已提交
739
{"uid": "test uid", "appId": "test appId", "realName": "张三", "idCard": "10xxxxxxxxxxx09", "metaInfo": "test metaInfo"}
C
chenruilong 已提交
740 741 742 743
```

Request Body 说明

C
chenruilong 已提交
744 745 746 747 748 749 750
| 名称         | 类型      | 必须  | 说明                     |
|------------|---------|-----|------------------------|
| uid        | string  | 是   | 业务系统中的用户id             |
| appId      | string  | 是   | uni-frv-external的appId |
| realName		 | String	 | 是		 | 用户真实姓名									        |
| idCard			  | String	 | 是		 | 用户身份证号									        |
| metaInfo		 | String	 | 是		 | 客户端获取设备信息返回的metaInfo	  |
C
chenruilong 已提交
751 752 753

Response Body 说明

C
chenruilong 已提交
754 755 756 757 758
| 名称        | 类型     | 必须  | 说明                         |
|-----------|--------|-----|----------------------------|
| errCode   | string | 是   | 错误码;成功返回0,其他错误返回错误码        |
| errMsg    | string | 否   | 错误信息;成功为空                  |
| certifyId | string | 是   | 认证id,用于客户端调用认证接口及云函数获取认证结果 |
C
chenruilong 已提交
759

C
chenruilong 已提交
760
**获取认证结果(getAuthResult)**
C
chenruilong 已提交
761

C
chenruilong 已提交
762 763 764 765
请求地址:
```
POST https://{云函数Url化域名}/{自定义路径}/getAuthResult
```
C
chenruilong 已提交
766

C
chenruilong 已提交
767
以下示例的请求地址均为示例,在实际使用中将更换为云函数URL化地址。
C
chenruilong 已提交
768 769 770

HTTP 示例
```javascript
C
chenruilong 已提交
771 772 773 774
POST /uni-frv-external-co/getAuthResult HTTP/1.1
Host: xxxx.com
Unicloud-S2s-Timestamp: 1676882808550
Unicloud-S2s-Signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
C
chenruilong 已提交
775 776 777
Content-Type: application/json
Cache-Control: no-cache

C
chenruilong 已提交
778
{"appId": "test appId", "certifyId": "sha24c5e9c4f6a3b167f26aae66bb20f"}
C
chenruilong 已提交
779 780 781 782
```

Request Body 说明

C
chenruilong 已提交
783 784 785 786 787 788 789
| 名称        | 类型     | 必须  | 说明                     |
|-----------|--------|-----|------------------------|
| appId     | string | 是   | uni-frv-external的appId |
| certifyId | string | 是   | 认证id                   |

Response Body 说明

C
chenruilong 已提交
790 791
| 名称       | 类型     | 必须  | 说明                              |
|----------|--------|-----|---------------------------------|
C
chenruilong 已提交
792 793
| errCode  | string | 是   | 错误码;成功返回0,其他错误返回错误码             |
| errMsg   | string | 否   | 错误信息;成功为空                       |
C
chenruilong 已提交
794 795 796 797
| uid      | string | 是   | 业务系统中的用户id                      |
| realName | string | 是   | 真实姓名                            |
| idCard   | string | 是   | 身份证号码                           |
| photo    | string | 是   | 用户认证照片;needAlivePhoto为true时返回   |
C
chenruilong 已提交
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
| status   | number | 是   | 认证状态:0 未认证 1 等待认证 2 认证通过 3 认证失败 |

**错误码**

| 错误码                                 | 说明               |
|-------------------------------------|------------------|
| uni-frv-invalid-param               | 请求参数错误           |
| uni-frv-param-required              | 缺少参数: {param}    |
| uni-frv-fail                        | 人脸识别认证失败         |
| uni-frv-frv-processing              | 等待人脸识别           |
| uni-frv-realname-verified           | 该账号已实名认证         |
| uni-frv-idcard-exists               | 该证件号码已绑定账号       |
| uni-frv-invalid-idcard              | 身份证号码不合法         |
| uni-frv-invalid-realname            | 姓名不合法,只能是汉字      |
| uni-frv-unknown-error               | 未知错误;常见于查询认证结果异常 |
| uni-frv-realname-verify-upper-limit | 当日实名认证次数已达上限     |
| uni-frv-config-field-required       | 缺少配置项: {field}   |
| uni-frv-config-field-invalid        | 配置项: {field}无效   |
| uni-frv-certify-id-not-exist        | certifyId 不存在    |
| uni-frv-certify-id-used             | certifyId 已使用    |
| uni-frv-callback-fail               | 服务异常,请稍后再试       |
| uni-frv-illegal-request             | 非法请求;签名错误时会返回此错误 |