Java_百度人脸识别登录

1、引入pom文件
这里去除了百度自带的slf4j-simple日志文件

<dependency>
	<groupId>com.baidu.aip</groupId>
		<artifactId>java-sdk</artifactId>
		<version>4.15.1</version>
		<!-- 去除slf4j-simple依赖包-start -->
		<exclusions>
			<exclusion>
				<groupId>org.slf4j</groupId>
 				<artifactId>slf4j-simple</artifactId>
 			</exclusion>
 		</exclusions>
 		<!-- 去除slf4j-simple依赖包-end -->
</dependency>

2、创建faceUtil工具类,并添加相关方法
APP_ID在百度云控制台中创建;
API_KEY与SECRET_KEY是在创建完毕应用后,系统分配给用户的,均为字符串,用于标识用户,为访问做签名验证,可在AI服务控制台中的应用列表中查看;
GROUP_ID是你创建的用户组名称;
IMAGE_TYPE:图片类型
BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;
URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。

import com.baidu.aip.face.AipFace;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;


/**
 * @author 飞廉少将
 * @program: mcquay
 * @description: 百度人脸识别Aip参数和相关方法
 * @time 2020/8/11
 */
public class FaceUtil {

    //设置App_id、Api_key、secret_key、group_id
    public static final String APP_ID = "*******";
    public static final String API_KEY = "*******";
    public static final String SECRET_KEY = "*******";
    public static final String GROUP_ID = "*******";
    public static final String IMAGE_TYPE = "BASE64";
//    public static final String IMAGE_TYPE = "URL";

    private static AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY);

    //创建单例的原因是避免多次获取sdk
    public static AipFace getClient() {
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);
        return client;
    }

    private static HashMap<String, String> options = new HashMap<String, String>();

    public FaceUtil() {
        options.put("quality_control", "NORMAL");
        options.put("liveness_control", "LOW");
    }


    /**
     * 人脸注册:
     * 将用户照片存入人脸库中
     *
     * @param image  取决于image_type参数,传入BASE64字符串或URL字符串或FACE_TOKEN字符串
     * @param userId 用户id
     * @return
     */
    public static String faceRegister(String image, String userId) {

        JSONObject res = client.addUser(image, IMAGE_TYPE, GROUP_ID, userId, options);
        String faceToken = res.getJSONObject("result").getString("face_token");
        return faceToken;
    }

    /**
     * 人脸更新方法:
     * 1、用于对人脸库中指定用户,更新其下的人脸图像
     * 2、针对一个uid执行更新操作,新上传的人脸图像将覆盖此uid原有所有图像。
     *
     * @param image  取决于image_type参数,传入BASE64字符串或URL字符串或FACE_TOKEN字符串
     * @param userId 用户id
     * @return
     */
    public static String faceUpdate(String image, String userId) {

        JSONObject res = client.updateUser(image, IMAGE_TYPE, GROUP_ID, userId, options);
        JSONObject result = res.getJSONObject("result");
        String faceToken = result.getString("face_token");
        return faceToken;
    }

    /**
     * 人脸检测:
     * 1、检测图片中的人脸并标记出位置信息
     *
     * @param image 取决于image_type参数,传入BASE64字符串或URL字符串或FACE_TOKEN字符串
     * @return
     */
    public static Boolean faceDetect(String image) {

        //传入可选参数调用接口
//        options.put("face_type", "LIVE");


        JSONObject res = client.detect(image, IMAGE_TYPE, options);
//        JSONObject result = res.getJSONObject("result");
//        JSONObject faceList = result.getJSONArray("face_list").getJSONObject(0);
//        String faceToken = faceList.getString("face_token");
        if (res.has("error_code") && res.getInt("error_code") == 0) {
            JSONObject resultObject = res.getJSONObject("result");
            Integer faceNum = resultObject.getInt("face_num");
            return faceNum == 1 ? true : false;
        } else {
            return false;
        }
    }

    /**
     * 人脸查找:查找人脸库中最相似的人脸并返回数据
     * 处理:用户的匹配得分(score)大于80分,即可认为是同一个用户
     */
    public static String faceSearch(String image) {
        JSONObject res = client.search(image, IMAGE_TYPE, GROUP_ID, options);
        if (res.has("error_code") && res.getInt("error_code") == 0) {
            JSONObject result = res.getJSONObject("result");
            JSONArray userList = result.getJSONArray("user_list");
            if (userList.length() > 0) {
                JSONObject user = userList.getJSONObject(0);
                double score = user.getDouble("score");
                if (score > 80) {
                    return user.getString("user_id");
                }
            }
        }
        return null;
    }

    /**
     * 查询用户人脸列表,并返回faceToken
     *
     * @param userId
     */
    public static String faceGetlist(String userId) {
        // 用户人脸列表
        JSONObject res = client.faceGetlist(userId, GROUP_ID, options);
        JSONObject result = res.getJSONObject("result");
        JSONArray faceList = result.getJSONArray("face_list");
        if (faceList.length() > 0) {

            JSONObject user = faceList.getJSONObject(0);
            String faceToken = user.getString("face_token");
            return faceToken;
        }
        return null;
    }
}

3、相关方法调用
这里要注意一点:因为face_toke是唯一的,所以我在第一次人脸注册的时候,是直接将返回的face_toke存在数据对应的字段中,然后通过人脸查找方法中返回了用户id(这里的用户id是需要自己设置的,可以是id+特定规则,因为我是这样设置的),然后通过用户id查到用户信息,返回face_toke,如果face_toke和存在数据库中的相同,则登录成功

/**
 * @author 飞廉少将
 * @program: mcquay
 * @description: 人脸识别服务层
 * @time 2020/8/13
 */
@Service
public class ReportFaceAipService {
	
	@Autowired
    private ReportFaceAipClient faceAipClient;
    
	//查询当前登录用户的指纹和人脸识别状态
    public ResultVO<Map> queryByBiotaStatues() {
        ReportUser admin = this.queryUser();	//获取当前登录人信息
        ResultVO<ReportUser> resultVO = faceAipClient.queryByBiotaStatues(admin.getId());

        Map<String, Object> map = new HashMap<>();
        if (resultVO.getData().getFingerPrintStatus() == 0) {
            map.put("fingerPrintStatus", true);
        } else {
            map.put("fingerPrintStatus", false);
        }
        if (resultVO.getData().getFaceStatus() == 0) {
            map.put("faceStatus", true);
        } else {
            map.put("faceStatus", false);
        }
        return ResponseUtil.ok(map);
    }
	
	//人脸检测和人脸查找
    public ResultVO<String> faceDetect(MultipartFile file) {
        try {
            String encode = Base64Util.encode(file.getBytes());
            //人脸检测
            Boolean flag = FaceUtil.faceDetect(encode);
            if (flag) {
                //人脸搜索
                String userId = FaceUtil.faceSearch(encode);
                if (!StringUtils.isEmpty(userId)) {
                    //查询人脸列表
                    String faceToken = FaceUtil.faceGetlist(userId);
                    return ResponseUtil.ok(faceToken);
                } else {
                    return ResponseUtil.fail("000", "无法识别面部信息,请重试!!!");
                }
            } else {
                return ResponseUtil.fail("000", "无法识别面部信息!!!");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseUtil.serious();
        }
    }
	
	//人脸注册
    public ResultVO<Boolean> faceRegister(MultipartFile file) {
        try {
            ReportUser user = this.queryUser();
            String userId = user.getId() + "_mcquay";

            String encode = Base64Util.encode(file.getBytes());
            Boolean flag = FaceUtil.faceDetect(encode);
            if (flag) {
                String faceToken;
                BiotaInfoVO infoVO = new BiotaInfoVO();
                infoVO.setId(user.getId());
                infoVO.setFaceStatus(true);
                if (!StringUtils.isEmpty(user.getFaceToken())) {
                    faceToken = FaceUtil.faceUpdate(encode, userId);
                    infoVO.setFaceToken(faceToken);
                } else {
                    faceToken = FaceUtil.faceRegister(encode, userId);
                    infoVO.setFaceToken(faceToken);
                }
                ResultVO<Boolean> resultVO = this.faceAipUpdate(infoVO);
                return resultVO;
            } else {
                return ResponseUtil.fail("000", "无法识别面部信息!!!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.serious();
        }
    }
}

4、登录

/**
 * @author 飞廉少将
 * @program: mcquay
 * @description: 人脸识别及指纹相关方法 前端控制器
 * @time 2020/8/13
 */
@RestController
@RequestMapping("/web/faceAip")
@Validated
@Api(tags = "人脸识别登录相关方法")
public class WebFaceAipController {
	
	@Autowired
    private ReportFaceAipService faceAipService;

	//人脸检测和人脸查找
    @ApiOperation(value = "人脸检测和人脸查找", httpMethod = "POST")
    @PostMapping(value = "/faceDetect", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResultVO<String> faceDetect(@RequestPart(required = false, value = "file") MultipartFile file) {
        return faceAipService.faceDetect(file);
    }
	
	//人脸注册并更新当前登录用户信息
    @ApiOperation(value = "人脸注册或更新当前登录用户脸部信息", httpMethod = "POST")
    @PostMapping(value = "/faceRegister", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResultVO<Boolean> faceRegister(@RequestPart(required = false, value = "file") MultipartFile file) {

        return faceAipService.faceRegister(file);
    }

	@ApiOperation(value = "关闭人脸识别", notes = "关闭人脸识别")
    @PostMapping("/faceAipUpdate")
    public ResultVO<Boolean> faceAipUpdate(@RequestBody BiotaInfoVO biotaInfoVO) {
        //获取当前登录用户信息
        Subject subject = SecurityUtils.getSubject();
        ReportUser user = (ReportUser) subject.getPrincipals().asList().get(0);

        //查询用户实时信息
        WebUserDetailVO data = userService.queryById().getData();
        if (data.getFaceToken().equals(biotaInfoVO.getFaceToken())) {
            biotaInfoVO.setId(user.getId());
            return faceAipService.faceAipUpdate(biotaInfoVO);
        }else {
            return ResponseUtil.fail("000","面部信息识别失败!!!");
        }
    }
	
	@PostMapping("/fingerPrintLogin")
    @ApiOperation(value = "指纹或人脸识别登录", notes = "指纹或人脸识别登录")
    public Object fingerPrintLogin(@RequestBody String body, HttpServletRequest request) {
        String type = JacksonUtil.parseString(body, "type");
        ReportUser reportUser;
        if (Integer.valueOf(type) == 1) {
            String fingerPrint = JacksonUtil.parseString(body, "fingerPrint");
            reportUser = faceAipService.queryByFingerPrint(fingerPrint);
        } else {
            String faceToken = JacksonUtil.parseString(body, "faceToken");
            reportUser = faceAipService.queryByFaceToken(faceToken);
        }
        if (reportUser == null) {
            return ResponseUtil.fail("000", "找不到相关信息,请使用账号密码登录!!!");
        } else {
            Subject currentUser = SecurityUtils.getSubject();

            try {
                currentUser.getSession().setTimeout(2592000000L);
                currentUser.login(new UsernamePasswordToken(reportUser.getUserAccount(), reportUser.getUserPassword()));
            } catch (UnknownAccountException uae) {
                uae.printStackTrace();
                logHelper.logAuthFail("登录", "找不到相关指纹或人脸信息,请使用账号密码登录!!!!!!");
                return ResponseUtil.fail(WebResponseCode.AUTH_INVALID_ACCOUNT, "找不到相关指纹或人脸信息,请使用账号密码登录!!!");
            } catch (LockedAccountException lae) {
                lae.printStackTrace();
                logHelper.logAuthFail("登录", "用户帐号已锁定或密码已过期不可用");
                return ResponseUtil.fail(WebResponseCode.AUTH_INVALID_ACCOUNT, "用户帐号已锁定或密码已过期不可用");

            } catch (AuthenticationException ae) {
                ae.printStackTrace();
                logHelper.logAuthFail("登录", "认证失败");
                return ResponseUtil.fail(WebResponseCode.AUTH_INVALID_ACCOUNT, "认证失败");
            }

            currentUser = SecurityUtils.getSubject();
            ReportUser admin = (ReportUser) currentUser.getPrincipal();

            logHelper.logAuthSucceed("登录");
            //将token存入redis
            BusinessTokenManager.saveToken(admin.getId(), currentUser.getSession().getId().toString());
            // userInfo
            Map<String, Object> adminInfo = new HashMap<String, Object>();
            adminInfo.put("acount", admin.getUserAccount());
            adminInfo.put("avatar", admin.getPic());
            adminInfo.put("realname", admin.getUserName());
            adminInfo.put("deptIds", admin.getDeptIds());
            adminInfo.put("deptNames", admin.getDeptNames());
            adminInfo.put("userMobile", admin.getUserMobile());
            adminInfo.put("roleId", admin.getRoleId());
            adminInfo.put("roleName", admin.getRoleName());
            adminInfo.put("pid", admin.getPid());
            adminInfo.put("pname", admin.getPname());
            adminInfo.put("faceToken",admin.getFaceToken());

            Map<Object, Object> result = new HashMap<Object, Object>();

            //添加日志记录
            ResultVO<Integer> resultVO = integralLogService.userIntegralLog(admin, 1);
            if (resultVO.getData() > 0) {
                result.put("integralLog", true);
            }else {
                result.put("integralLog",resultVO.getData());
            }
            result.put("token", currentUser.getSession().getId());
            result.put("adminInfo", adminInfo);
            return ResponseUtil.ok(result);
        }
    }

}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值