android客户端直接调用芝麻信用的人脸认证.

芝麻信用,人脸认证

Posted by Mtj on July 6, 2017
  • 按理说,这些都应该是服务端完成的事情。可是由于种种原因,我放了一句狠话。。。然后只能自己搞了。。。。

  • 1、由于芝麻信用提供的SDK,在android端直接使用SSL证书验证是不通过的。所以当时有点后悔说的狠话。
  • 2、SDK用不了,没办法只能自己动手,自己拼接参数,写请求。
  • 3、不废话,直接开始。

  • (1)、解压下载的SDK源码。 找到 WebUtils.java (在解压后的“com\antgroup\zmxy\openplatform\api\internal\util”目录下)。打开 WebUtils.java 查看源码。 找到“getConnection()”方法,你会看到很蛋疼的一句话“默认认证不通过,进行证书校验。” 要解压的包

这里写图片描述

这里写图片描述

  • 我们修改 return true; //默认认证不通过,进行证书校验。(真操蛋,直接改成true,看你还怎么不给我通过)。之后保存,把webutils.java 复制到自己的工程中,调用芝麻信用时使用。

  • (2)、自己拼参数,开始认证。就直接上代码了。

public class FaceUtils {
	private String path = "";//回调地址
	private static String biz_no = "";
	private Context context;
	private static FaceUtils faceUtils;
	private String IP = "https://zmopenapi.zmxy.com.cn/openapi.do";
	private String app_id = "自己的APP_ID";
	private String private_key = "自己的私钥";
	private String public_key = "支付宝的公钥(不是应用公钥,别搞错了)";

	private AdapterViewClickListener clickListener;

	public static FaceUtils getInstance() {
		if (faceUtils == null) {
			faceUtils = new FaceUtils();
		}
		return faceUtils;
	}

	/**
	 * 启动芝麻认证
	 * 
	 * @param name
	 * @param id_num
	 */
	public void startFace(Context context, final String name,
			final String id_num,String path) {
		this.path = path;
		this.context = context;
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				String params = "";
				String sign = "";
				JSONObject identity_param = new JSONObject();
				try {
					identity_param.put("identity_type", "CERT_INFO");
					identity_param.put("cert_type", "IDENTITY_CARD");
					identity_param.put("cert_name", name);
					identity_param.put("cert_no", id_num);
				} catch (JSONException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				long time = System.currentTimeMillis();
				String signCanshu = "transaction_id=ZGYD"
						+ new SimpleDateFormat("yyyyMMddHHmmss").format(time)
						+ "0001234" + "&product_code=w1010100000000002978"
						+ "&biz_code=FACE" + "&identity_param="
						+ identity_param.toString() + "&ext_biz_param={}";
				try {
					params = RSACoderUtil.encrypt(signCanshu, "UTF-8",
							public_key);
					sign = RSACoderUtil.sign(signCanshu, "UTF-8", private_key);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Map<String, String> map = new HashMap<>();
				map.put("app_id", app_id);
				map.put("charset", "UTF-8");
				map.put("method", "zhima.customer.certification.initialize");
				map.put("version", "1.0");
				map.put("platform", "zmop");
				map.put("params", params);
				map.put("sign", sign);
				String result = "";
				try {
					result = com.huahan.finance.utils.WebUtils.doPost(IP, map,
							15000, 15000);
					HHLog.i("mtj", "result = " + result);
					try {
						JSONObject object = new JSONObject(result);
						String jieresult = RSACoderUtil.decrypt(
								object.getString("biz_response"), private_key,
								"UTF-8");
						HHLog.i("mtj", "解密== " + jieresult);
						JSONObject bizObject = new JSONObject(jieresult);
						biz_no = bizObject.getString("biz_no");
						handler.sendEmptyMessage(0);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						HHLog.i("mtj", "result 解密e= " + e.getMessage());
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					HHLog.i("mtj", "result e= " + e.getMessage());
				}
			}
		}).start();
	}

	/**
	 * 获取认证url
	 * 
	 * @param biz
	 */
	public void getUrl() {
		ZhimaCustomerCertificationCertifyRequest request = new ZhimaCustomerCertificationCertifyRequest();
		request.setPlatform("zmop");
		request.setBizNo(biz_no);// 必要参数
		// 设置回调地址,必填. 如果需要直接在支付宝APP里面打开回调地址使用alipay协议
		// alipay://www.taobao.com 或者 alipays://www.taobao.com,分别对应http和https请求
		request.setReturnUrl(path);// 必要参数
		DefaultZhimaClient client = new DefaultZhimaClient(
				"https://zmopenapi.zmxy.com.cn/openapi.do", app_id,
				private_key, public_key);
		try {
			String url = client.generatePageRedirectInvokeUrl(request);
			HHLog.i("mtj", "开始认证url==" + url);
			doVerify(url);
		} catch (ZhimaApiException e) {
			e.printStackTrace();
			HHLog.i("mtj", "开始认证错误==" + e.getMessage());
		}
	}

	public String Result(String params) {
		String result = "";
		try {
			result = RSACoderUtil.decrypt(params, private_key, "UTF-8");
		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;
	}

	/**
	 * 查询认证结果
	 * 
	 * @param biz
	 */
	public void QueryNum(AdapterViewClickListener clickListener) {
		this.clickListener = clickListener;
		if (!TextUtils.isEmpty(biz_no)) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					String params = "";
					String sign = "";
					String signCanshu = "biz_no=" + biz_no;
					try {
						params = RSACoderUtil.encrypt(signCanshu, "UTF-8",
								public_key);
						sign = RSACoderUtil.sign(signCanshu, "UTF-8",
								private_key);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					Map<String, String> map = new HashMap<>();
					map.put("app_id", app_id);
					map.put("charset", "UTF-8");
					map.put("method", "zhima.customer.certification.query");
					map.put("version", "1.0");
					map.put("platform", "zmop");
					map.put("params", params);
					map.put("sign", sign);
					String result = "";
					String passed = "";
					try {
						result = WebUtils.doPost(IP, map, 15000, 15000);
						JSONObject jsonObject = new JSONObject(result);
						JSONObject jObject = new JSONObject(
								RSACoderUtil.decrypt(
										jsonObject.getString("biz_response"),
										private_key, "UTF-8"));
						HHLog.i("mtj", "认证结果==" + jObject.toString());
						passed = jObject.getString("passed");
					} catch (Exception e) {
						e.printStackTrace();
						HHLog.i("mtj", "认证结果=e=" + e.getMessage());
					}
					Message message = new Message();
					message.what = 1;
					message.obj = passed;
					handler.sendMessage(message);
				}
			}).start();
		}
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			switch (msg.what) {
			case 0:// 认证
				getUrl();
				break;
			case 1:// 查询
				String passed = (String) msg.obj;
				if ("true".equals(passed)) {
					clickListener.adapterViewClick(1, null);
				} else {// 未通过
					clickListener.adapterViewClick(0, null);
				}
				biz_no = "";
				break;
			default:
				break;
			}
		}
	};

	/**
	 * 启动支付宝进行认证
	 * 
	 * @param url
	 *            开放平台返回的URL
	 * @param url
	 */
	@SuppressWarnings("deprecation")
	private void doVerify(String url) {
		if (hasApplication()) {
			Intent action = new Intent(Intent.ACTION_VIEW);
			StringBuilder builder = new StringBuilder();
			// 这里使用固定appid 20000067
			builder.append("alipays://platformapi/startapp?appId=20000067&url=");
			builder.append(URLEncoder.encode(url));
			action.setData(Uri.parse(builder.toString()));
			context.startActivity(action);
		} else {
			// 处理没有安装支付宝的情况
			DialogUtils.showOptionDialog(context,
					context.getString(R.string.load_zfb),
					new OnOptionDialogClickListener() {
						@Override
						public void onClick(Dialog paramDialog, View paramView) {
							// TODO Auto-generated method stub
							Intent action = new Intent(Intent.ACTION_VIEW);
							action.setData(Uri.parse("https://m.alipay.com"));
							action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
							context.startActivity(action);
							paramDialog.dismiss();
						}
					}, new OnOptionDialogClickListener() {
						@Override
						public void onClick(Dialog paramDialog, View paramView) {
							// TODO Auto-generated method stub
							paramDialog.dismiss();
						}
					}, true);
		}
	}

	/**
	 * 判断是否安装了支付宝
	 * 
	 * @return true 为已经安装
	 * @return
	 */
	private boolean hasApplication() {
		PackageManager manager = context.getPackageManager();
		Intent action = new Intent(Intent.ACTION_VIEW);
		action.setData(Uri.parse("alipays://"));
		List list = manager.queryIntentActivities(action,
				PackageManager.GET_RESOLVED_FILTER);
		return list != null && list.size() > 0;
	}
}
  • 认证的初始化、查询认证结果的参数请求都在上面的代码里,里面的一些结果的处理都是自己的demo里用到的。到时候都改成自己的结果处理就行了,请求参数是一样的。

  • OK,就是放狠话了,怎么了,嘿嘿。。。

  • 关于回调地址,再调起自己的APP内某个页面的方法,请参照,我之前的一篇文章JS启用本地安卓APP的方法