开发者在构建需要实名认证功能的小程序时,身份证识别往往是刚需。百度OCR作为国内领先的文字识别服务,提供了稳定高效的身份证识别API。本文将带你从零开始,避开所有可能的坑,完整实现微信小程序调用百度OCR进行身份证识别的全流程。
在开始编码前,我们需要完成百度AI平台的账号注册和应用创建。这个阶段看似简单,但有几个关键点容易出错:
账号注册与认证
访问百度AI开放平台官网,使用百度账号登录后,进入控制台。个人开发者需要完成实名认证,企业用户则需要提交营业执照等信息。认证过程通常需要1-3个工作日,建议提前完成。
创建应用与获取密钥
在控制台选择"文字识别"服务,创建新应用时需要注意:
创建成功后,记录下以下关键信息:
code复制API Key: xxxxxxxxxxxxxxxxxxxx
Secret Key: xxxxxxxxxxxxxxxxxxxx
AppID: xxxxxxxx
免费额度与计费规则
新用户通常有免费调用额度,但需要注意:
提示:建议在控制台设置"用量提醒",避免意外超额产生费用。
微信小程序调用第三方API有严格的安全限制,以下是必须完成的配置:
在小程序后台的"开发"-"开发设置"-"服务器域名"中,添加以下request合法域名:
code复制https://aip.baidubce.com
常见审核不通过的原因包括:
确保小程序已获取以下权限:
scope.camera(相机权限)scope.writePhotosAlbum(相册写入权限)scope.record(录音权限,虽然用不到但有时会误报)在app.json中声明所需权限:
json复制{
"permission": {
"scope.camera": {
"desc": "需要您的授权才能使用相机拍摄身份证"
},
"scope.writePhotosAlbum": {
"desc": "需要您的授权才能保存裁剪后的图片"
}
}
}
百度OCR接口需要Access Token进行鉴权,这里有几个优化点值得注意:
javascript复制const getAccessToken = () => {
return new Promise((resolve, reject) => {
const url = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${API_KEY}&client_secret=${SECRET_KEY}`
wx.request({
url,
method: 'POST',
success: (res) => {
if (res.data.access_token) {
resolve(res.data.access_token)
} else {
reject(new Error('获取Token失败'))
}
},
fail: reject
})
})
}
Access Token有效期为30天,但建议每次使用时检查是否过期:
javascript复制const CACHE_KEY = 'baidu_ocr_token'
const getCachedToken = async () => {
try {
const cache = wx.getStorageSync(CACHE_KEY)
if (cache && cache.expires > Date.now()) {
return cache.token
}
const newToken = await getAccessToken()
wx.setStorageSync(CACHE_KEY, {
token: newToken,
expires: Date.now() + 29 * 24 * 3600 * 1000 // 提前1天刷新
})
return newToken
} catch (error) {
console.error('Token获取失败:', error)
throw error
}
}
身份证识别对图片质量要求较高,以下是关键处理步骤:
提供两种获取图片的方式:
javascript复制// 选择图片方式
const chooseImage = () => {
wx.showActionSheet({
itemList: ['拍照', '从相册选择'],
success: (res) => {
if (res.tapIndex === 0) {
takePhoto()
} else {
selectFromAlbum()
}
}
})
}
// 拍照
const takePhoto = () => {
wx.chooseImage({
sourceType: ['camera'],
camera: 'back',
success: (res) => {
processImage(res.tempFilePaths[0])
}
})
}
百度OCR接口需要Base64格式的图片,注意以下几点:
data:image/png;base64,前缀javascript复制const fileToBase64 = (filePath) => {
return new Promise((resolve, reject) => {
wx.getFileSystemManager().readFile({
filePath,
encoding: 'base64',
success: (res) => {
resolve(res.data)
},
fail: reject
})
})
}
身份证识别需要清晰的正面或反面照片,使用Canvas进行智能裁剪:
javascript复制const clipIDCard = (imagePath) => {
return new Promise((resolve) => {
const query = wx.createSelectorQuery()
query.select('#clipCanvas')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const img = canvas.createImage()
img.onload = () => {
// 身份证在图片中的大致位置
const clipX = img.width * 0.1
const clipY = img.height * 0.2
const clipWidth = img.width * 0.8
const clipHeight = img.height * 0.25
canvas.width = clipWidth
canvas.height = clipHeight
ctx.drawImage(
img,
clipX, clipY, clipWidth, clipHeight,
0, 0, clipWidth, clipHeight
)
wx.canvasToTempFilePath({
canvas,
success: (res) => {
resolve(res.tempFilePath)
}
})
}
img.src = imagePath
})
})
}
javascript复制const recognizeIDCard = async (imageBase64, side = 'front') => {
const token = await getCachedToken()
return new Promise((resolve, reject) => {
wx.request({
url: `https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=${token}`,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
image: imageBase64,
id_card_side: side,
detect_risk: 'true' // 开启风险检测
},
success: (res) => {
if (res.data.error_code) {
reject(new Error(res.data.error_msg))
} else {
resolve(parseIDCardResult(res.data))
}
},
fail: reject
})
})
}
百度OCR返回的原始数据需要进一步处理:
javascript复制const parseIDCardResult = (data) => {
const result = {}
data.words_result.forEach(item => {
result[item.words_type] = {
text: item.words,
location: item.location
}
})
// 简单校验
if (result['公民身份号码'] &&
!/^\d{17}[\dXx]$/.test(result['公民身份号码'].text)) {
throw new Error('身份证号码格式不正确')
}
return {
...result,
riskType: data.risk_type,
imageStatus: data.image_status
}
}
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 获取Token失败 | API Key/Secret Key错误 | 检查控制台应用配置 |
| 识别返回空结果 | 图片质量差/方向错误 | 添加图片预处理步骤 |
| 网络请求超时 | 域名未配置/服务器问题 | 检查合法域名配置 |
性能优化
安全增强
用户体验
在实际项目中,我们发现身份证边缘留白约10%、图片亮度适中的情况下识别率最高。对于二代身份证,确保拍摄时所有信息清晰可见,特别是底部的数字号码区域。