1. 业务背景
公司要求实现类型微信二维码网页登录模式的手机签名。因为只是demo就没有深究,就只是通过异步方式简单实现。该业务模块是基于一个单点登录系统的子业务模块,所以签名等内容不理解没有关系。该文章主要是通过简要代码的梳理业务流程。
2. 大体流程如下
- 在login.jsp页面执行docReady()方法中的getHycSignature()方法开始进入二维码异步流程
-
getHycSignature()方法
将随机数和定向页面地址传到后台异步生成二维码,生成二维码成功则将生成的图片在login.jsp上显示。 - 第三方手机页面:对随机数进行签名,然后将签名值和证书实体传到后台,后台其和随机数一起保存到数据库
- 定时执行selectData()方法
selectData()主要是异步将页面随机数传到后台,通过随机数查询签名值和证书实体,得到后完成整个签名过程,登录系统,获得系统相关数据。
3. 部分代码内容
3.1 login.jsp前端代码
var HycPkiCom=document.getElementById("HycPkiCom");
var certSn;
var certInfo;
var signature;
var usercert;
function activeFun(){
var actFrm = document.getElementById("isActFrm");
actFrm.username.value = certSn;
actFrm.certInfo.value = certInfo;
actFrm.usercert.value = usercert;
actFrm.signature.value = signature;
actFrm.companyName.value = getCompanyName();
<%if (changeKey != null && changeKey.length() > 0) {%>
actFrm.action = "activeUser.jsp";
<%}%>
actFrm.submit();
}
function docReady(isOnload){
<%if(noApp == false){%>
var fsCA;
try{
fsCA = new ActiveXObject("PSIAtv.PSIAPP");
}catch(e){
alert("未安装数字证书客户端");
window.location.href="http://59.41.9.22/site/index-gd.html";
return;
}
if(true){
var Random = ‘<%=random%>‘;
getHycSignature(Random);//通过这个方法开始,进入二维码处理的异步代码
}else{
//alert("请插入key登陆");
document.getElementById("disableId").style.display="none";
document.getElementById("enableId").style.display="block";
}
<%} else {%>
return;
<%}%>
}
function getHycSignature(randomStr){
$.ajax({
data: getQRCode(),
async: false,
type: "POST",
dataType: ‘text‘,
url: "./oauth/genQRCodeController?method=handleRequestInternal",
error: function(data) {
alert("系统异常,请联系系统管理员:错误代码[getHycSignature]");
},
success: function(data) {
document.getElementById("img1").src=data;
document.getElementById("img1").style.display="block";
}
});
setInterval("selectData(‘"+randomStr+"‘)",5000);
}
function getQRCode(){
var randomTemp = "<%=random%>";
var urlTemp = "http://192.168.1.109:8181/oauth2spring/matrixSign.jsp";
return "operation=signature&randomTemp=" + randomTemp + "&urlTemp=" + urlTemp;
}
function selectData(randomStr) {
$.ajax({
data : "operation=selectData&selectRandom=" + randomStr,
async : false,
type : "POST",
dataType : ‘text‘,
url : "./oauth/genQRCodeController?method=handleRequestInternal",
error : function(data) {
//alert("系统异常,请联系系统管理员,错误代码[selectData]");
},
success : function(data) {
if (data != "") {
var res = data.split("&");
signature = res[0];//手机证书
var signCertStr = res[1];//手机签名值
if (signature != "") {
certInfo = HycPkiCom.GetCertInfo(signCertStr);//获取证书xml信息
certSn = certInfo.substring(certInfo.indexOf("<serialnum>") + 11, certInfo.indexOf("</serialnum>"));
activeFun();//组织数据,依据这些数据登录系统
}
}
}
});
}
3.2 手机签名页面
<%
String random = "";
if (request.getParameter("state") != null) {
random = (String) request.getParameter("state");
System.out.println("random="+random);
}
%>
<body>
<form id="form1" method ="post" action="oauth/genQRCodeController">
<input type="hidden" name="certSign" id="certSign" value=""/>
<input type="hidden" name="signData" id="signData" value=""/>
<input type="hidden" name="random" id="random" value="<%=random%>"/>
</form>
</body>
<script type="text/javascript">
var setupIndex = JsPKI.getSetupInfo("I");
var certSig = "";
var signData= "";
var userCert = "";
if(typeof(setupIndex) != "undefined" && setupIndex.length > 0){
certSig = JsPKI.GetCertByCertID(setupIndex);
signData = HycPKI.AdvSignData(‘D‘,‘<%=random%>‘,1,1);
if(signData!=""){
document.getElementById("l1").innerText ="签名已经完成,请留意电脑屏幕显示。";
document.getElementById("certSign").value=certSig;
document.getElementById("signData").value=signData;
document.getElementById("form1").submit();
}
}else{
alert(‘未选定默认证书,请选定默认证书!‘);
}
</script>
3.2 后台代码
用一个Controller处理,依据不同的operation执行不同的代码块(SpringMVC框架)操作数据库的代码这里就略啦。
public class GenQRCodeController extends AbstractController{
private QRCodeSignDao qRCodeSignDao;
public void setqRCodeSignDao(QRCodeSignDao qRCodeSignDao) {
this.qRCodeSignDao = qRCodeSignDao;
}
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
System.out.println("==========进入GenQRCodeController==========");
String operation = request.getParameter("operation");
if("selectData".equals(operation)){
String selectRandom = request.getParameter("selectRandom");
System.out.println("check random sign status="+selectRandom);
List list =qRCodeSignDao.getQrcodeModelByRandom(selectRandom);
if(list.size()>0){
QrcodeSignModel qrcodeSignModel = (QrcodeSignModel)list.get(0);
String res = qrcodeSignModel.getSignData()+"&"+qrcodeSignModel.getCertSign();
response.getWriter().write(res);
return null;
}
return null;
}
if("signature".equals(operation)){
String sno = request.getParameter("randomTemp");
String url = request.getParameter("urlTemp");
String json = "{\"sno\":\"<sno>\",\"authorizationurl\":\"<authorizationurl>\"}";
json = json.replace("<authorizationurl>",url + "?state=" + sno);
json = json.replace("<sno>", sno);
System.out.println(json);
String content = new String(json.getBytes("UTF-8"), "iso-8859-1");
QRCodeWriter writer = new QRCodeWriter();
try {
BitMatrix matrix = writer.encode(content, BarcodeFormat.QR_CODE, 300, 300);
String fileName = "matrix.png";
String filePath = request.getSession().getServletContext().getRealPath("/")+fileName;
FileOutputStream os = new FileOutputStream(filePath);
MatrixToImageWriter.writeToStream(matrix, "png", os);
os.flush();
os.close();
response.getWriter().write(fileName);
} catch (WriterException e) {
e.printStackTrace();
}
}
String certSign = request.getParameter("certSign")!=null?(String) request.getParameter("certSign"):"";
String signData = request.getParameter("signData")!=null?(String) request.getParameter("signData"):"";
String random = request.getParameter("random")!=null?(String) request.getParameter("random"):"";
if(!"".equals(certSign)&&!"".equals(signData)){
QrcodeSignModel qrcodeSignModel = new QrcodeSignModel();
qrcodeSignModel.setCertSign(certSign);
qrcodeSignModel.setRandom(random);
qrcodeSignModel.setSignData(signData);
qRCodeSignDao.addQrcodeModel(qrcodeSignModel);
}
return null;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。