活体检测代码提交
This commit is contained in:
@ -1,15 +1,17 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { Form, Button, Input, Row, Col, Modal, Spin, message, Tabs } from 'antd';
|
||||
import { UserOutlined, LockOutlined, SafetyCertificateOutlined, VideoCameraOutlined } from '@ant-design/icons';
|
||||
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
|
||||
import './style.less';
|
||||
import { changePass, rgbToBase64 } from './service';
|
||||
import { changePass } from './service';
|
||||
import logo from '@/images/login/logoPic.png';
|
||||
import { refreshTokenApi, ZjfakeAccountLogin, ZjfakeFaceLogin } from '@/services/login';
|
||||
import { history } from 'umi';
|
||||
import cookie from 'react-cookies';
|
||||
import moment from 'moment';
|
||||
import FrameFaceLogin from '../faceLogin/FrameFaceLogin';
|
||||
import { fromPairs } from 'lodash';
|
||||
import Living from './living.min.js';
|
||||
import { _KJUR } from './jsrsasign-latest-all-min';
|
||||
import { time } from 'echarts';
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 7 },
|
||||
@ -35,7 +37,147 @@ const Index: React.FC<{}> = () => {
|
||||
const mediaStreamTrack = useRef<any>();
|
||||
const { TabPane } = Tabs;
|
||||
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||
const [faceLoginDisable, setFaceLoginDisable] = useState<boolean>(false);
|
||||
const [faceLoginDisable, setFaceLoginDisable] = useState<boolean>(false);
|
||||
const lv = useRef<Living>();
|
||||
const [timerShow, setTimeShow] = useState<boolean>(false);
|
||||
const [itemShow, setItemShow] = useState<boolean>(false);
|
||||
const [action, setAction] = useState<number>(1);
|
||||
const [timer, setTimer] = useState<number>(10000);
|
||||
/**
|
||||
* 设置活体检测token
|
||||
*/
|
||||
const setLiveDetectToken = () =>{
|
||||
let appKey= 'nkYy3g1yT0alE8pF6a1UTC4I'
|
||||
let appSecrect = 'L30zHpTyAtTlY7tTCpbzdxxKCQgwWIQL'
|
||||
// Header
|
||||
var header = {
|
||||
typ: "JWT", // 声明类型
|
||||
alg: "HS256" // 声明加密的算法 通常直接使用 HMAC SHA256
|
||||
};
|
||||
|
||||
var payload = {
|
||||
iss: appKey,
|
||||
iat: moment().unix(),
|
||||
exp: moment()
|
||||
.add(29, "minutes")
|
||||
.unix()
|
||||
};
|
||||
var sHeader = JSON.stringify(header);
|
||||
var sPayload = JSON.stringify(payload);
|
||||
var sJWT = _KJUR.jws.JWS.sign("HS256", sHeader, sPayload, {
|
||||
utf8: appSecrect,
|
||||
});
|
||||
console.log(sJWT);
|
||||
return sJWT;
|
||||
};
|
||||
/**
|
||||
* 开始人脸识别(活体和比对)
|
||||
*/
|
||||
const liveDetectStart = () => {
|
||||
liveDetectStop();
|
||||
let _lv = new Living(null, {
|
||||
timer: 10000,
|
||||
action : [1,3,2],
|
||||
token: setLiveDetectToken(),
|
||||
proxy:'/living/api',
|
||||
getFacePicture:()=>{
|
||||
return getLiveDetectFile()
|
||||
},
|
||||
//开始活体检测,此时token已鉴权成功
|
||||
onDetectStart:()=>{
|
||||
setSubmitLoading(true);
|
||||
},
|
||||
//每轮检测开始
|
||||
onDetectActionStart:(action:number)=>{
|
||||
setAction(action);
|
||||
// this.drawCanvas()
|
||||
},
|
||||
//每轮检测计时
|
||||
onDetectActionProgress:(action:number,timer:number)=>{
|
||||
setTimer(timer);
|
||||
},
|
||||
//每轮检测结束
|
||||
onDetectActionFinish:(action:number,data:any)=>{
|
||||
// this.clearCanvas()
|
||||
setTimer(10000);
|
||||
console.log(data)
|
||||
},
|
||||
//活体检测完成
|
||||
onDetectFinish:(data:any)=>{
|
||||
if(data.code == 1){
|
||||
setAction(4);
|
||||
setTimeShow(false);
|
||||
//人脸比对
|
||||
hanleFaceSubmit(data.file.file, null);
|
||||
}else{
|
||||
message.error('活体检测失败');
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
// data.code === 1? message.success('活体检测通过'):message.error('活体检测失败')
|
||||
}
|
||||
});
|
||||
//开始检测
|
||||
_lv.start();
|
||||
lv.current = _lv;
|
||||
}
|
||||
/**
|
||||
* 停止活体检测
|
||||
*/
|
||||
const liveDetectStop = () => {
|
||||
lv.current && lv.current.stop();
|
||||
}
|
||||
/**
|
||||
* 给活体检测提供照片
|
||||
* @returns 活体照片
|
||||
*/
|
||||
const getLiveDetectFile = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('width', '300');
|
||||
canvas.setAttribute('height', '200');
|
||||
const context = canvas.getContext('2d');
|
||||
context.drawImage(video.current, 0, 0, 300, 200);
|
||||
let _imgURI = canvas.toDataURL("image/jpeg",);
|
||||
console.log(_imgURI);
|
||||
let _file = base64ToBlob(_imgURI);
|
||||
return {
|
||||
file:_file//传给活体检测服务的文件
|
||||
}
|
||||
}
|
||||
const classColor = (action:any) => {
|
||||
let color = '';
|
||||
switch(action){
|
||||
case 1:
|
||||
color = '#409eff';
|
||||
break;
|
||||
case 2:
|
||||
color = '#5daf34';
|
||||
break;
|
||||
case 3:
|
||||
color = 'gold';
|
||||
break;
|
||||
case 4:
|
||||
color = 'grey';
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
const actionText = (action:number, timer:number) => {
|
||||
let text = '';
|
||||
switch(action){
|
||||
case 1:
|
||||
text = '对准摄像头眨眨眼('+ timer + 's)';
|
||||
break;
|
||||
case 2:
|
||||
text = '对准摄像头张张嘴('+ timer + 's)';
|
||||
break;
|
||||
case 3:
|
||||
text = '对准摄像头摇摇头('+ timer + 's)';
|
||||
break;
|
||||
case 4:
|
||||
text = '请稍候,正在验证中...';
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
const genRandomString = (len: number) => {
|
||||
const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
@ -138,6 +280,7 @@ const Index: React.FC<{}> = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('width', '300');
|
||||
canvas.setAttribute('height', '200');
|
||||
document.body.appendChild(canvas);
|
||||
const context = canvas.getContext('2d');
|
||||
context.drawImage(video.current, 0, 0, 300, 200);
|
||||
canvas.toBlob(function (result: any) {
|
||||
@ -236,9 +379,9 @@ const Index: React.FC<{}> = () => {
|
||||
};
|
||||
//访问用户媒体设备的兼容方法
|
||||
const InitUserMedia = (constraints: any, success: any, error: any) => {
|
||||
if (navigator.mediaDevices.getUserMedia) {
|
||||
if (navigator.mediaDevices?.getUserMedia) {
|
||||
//最新的标准API
|
||||
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
|
||||
navigator.mediaDevices?.getUserMedia(constraints).then(success).catch(error);
|
||||
} else if (navigator.webkitGetUserMedia) {
|
||||
//webkit核心浏览器
|
||||
navigator.webkitGetUserMedia(constraints, success, error);
|
||||
@ -285,17 +428,16 @@ const Index: React.FC<{}> = () => {
|
||||
return new Blob([uInt8Array], { type: contentType });
|
||||
};
|
||||
|
||||
//RgbToBase64
|
||||
const RgbToBase64 = async (image: any) => {
|
||||
//IELiveDetectFinish
|
||||
const IELiveDetectFinish = async (data: any) => {
|
||||
setSubmitLoading(true);
|
||||
// await rgbToBase64({ image }).then(res => {
|
||||
// const _blob = base64ToBlob('data:image/jpg;base64,' + res.data);
|
||||
// hanleFaceSubmit(_blob, null);
|
||||
// }).catch(e => {
|
||||
// setSubmitLoading(false);
|
||||
// });
|
||||
console.log(1, image);
|
||||
hanleFaceSubmit(base64ToBlob(image), null);
|
||||
setAction(4);
|
||||
hanleFaceSubmit(base64ToBlob(data.file.file), null);
|
||||
}
|
||||
|
||||
const UpdateDetectStatus = async(action:number, timer:number)=>{
|
||||
setAction(action);
|
||||
setTimer(timer);
|
||||
}
|
||||
|
||||
//是https或者是本地
|
||||
@ -415,7 +557,8 @@ const Index: React.FC<{}> = () => {
|
||||
className="form-box"
|
||||
initialValues={{ remember: true }}
|
||||
form={form2}
|
||||
onFinish={hanleFaceSubmit.bind(this, null)}
|
||||
// onFinish={hanleFaceSubmit.bind(this, null)}
|
||||
onFinish={!whetherIE.current?liveDetectStart:hanleFaceSubmit.bind(this, null)}
|
||||
// onFinishFailed={onFinishFailed}
|
||||
>
|
||||
<Form.Item
|
||||
@ -431,13 +574,20 @@ const Index: React.FC<{}> = () => {
|
||||
/>
|
||||
</Form.Item>
|
||||
{/* 加载摄像头 */}
|
||||
{/* <Form.Item hidden={!itemShow}>
|
||||
<div>
|
||||
<span style={{color:classColor(action)}}>{actionText(action)}</span>
|
||||
<span hidden={!timerShow}>{Math.round(timer/1000)}</span>
|
||||
</div>
|
||||
</Form.Item> */}
|
||||
<Form.Item>
|
||||
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>) : (<FrameFaceLogin faceCompareEvent={RgbToBase64} />)}
|
||||
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>) : (<FrameFaceLogin faceCompareEvent={IELiveDetectFinish} faceDetectStatusEvent = {UpdateDetectStatus}/>)}
|
||||
{/* <video ref={video} width="382" height="200"></video> */}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{/* onClick={() => {hanleFaceSubmit(null, null);}} */}
|
||||
<Button type="primary" className="w100" loading={submitLoading} htmlType="submit">
|
||||
{submitLoading ? '请稍候,正在验证中...' : '登 录'}
|
||||
{submitLoading ? actionText(action, Math.round(timer/1000)) : '登 录'}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
Reference in New Issue
Block a user