最近做了一个系统的短信验证与登录的功能,这里简述一下实现方法。
前端方面,像众多系统一样,jsp页面上有两个输入栏,一栏输入手机号,一栏输入验证码,输入验证码邮编是点击发送验证码,点击之后开始60s倒计时。且用js写好对手机号规则验证的正则表达式。js还有两个核心方法,一个是点击发送验证码时调用后端controller中的messageSend方法,一个是点击提交时调用后端controller中的checkVcode方法。核心代码如下:
$('.hmac').on('click',function(){
if(!/^(13[0-9]|15[012356789]|17[0-9]|18[0-9]|14[57])[0-9]{8}|(170[059])[0-9]{6}$/i.test($('#phone').val())){
layer.msg("请输入正确的手机号");
return ;
}
var codeflag = 60;
if(phoneflag == 1&&codeflag==60){
var timeflag = setInterval(function(){
codeflag--;
if(codeflag>0){
$('.hmac').val('重新发送'+codeflag+'s');
$('.hmac').css({'color':'#99897A','border':'1px solid #99897A'});
$('.hmac').attr('disabled','disabled');
}else{
codeflag=60;
$('.hmac').val('获取验证码');
$('.hmac').css({'color':'#68371D'});
$('.hmac').removeAttr('disabled');
clearInterval(timeflag);
}
},1000);
BaseUtils.ajaxAction_nomsg("login/messageSend", {
phone:$('#phone').val()
}, {
success: function(data) {
//alert(data);
}, error : function(data) {
layer.msg(data.message);
}
});
}
})
function checkUser(){
var phone = $('#phone').val();
var vcode = $('#vcode').val()
if(phone == "" ){
layer.msg("请输入手机号");
return false;
}
if(vcode == "" ){
layer.msg("请输入验证码");
return false;
}
if(typeof(phone)!="undefined"&&typeof(vcode)!="undefined"){
BaseUtils.ajaxAction_nomsg("login/checkVcode", {
phone:phone,
vcode:vcode
}, {
success: function(data) {
$("form").submit();
}, error : function(data) {
layer.msg('验证码错误');
}
},
false);
}else{
layer.msg('登录用户信息错误');
return false;
}
}
后端方面,购买一个发短信的第三方平台接口,调用其接口即可对相应手机号进行短信发送。查看相关接口文档,得到可以使用来发短信的id,用户名和密码。用户输入的电话可通过前端jsp的form表单提交至后端,后端控制器使用request.getParameter得到这个字段,再将以文档规范调用短信发送接口,即可实现短信发送功能。核心代码如下:
//发送短信
@RequestMapping(value = "messageSend")
public void messageSend(HttpServletRequest request, HttpServletResponse response) throws IOException{
String tel = request.getParameter("phone");
JSONObject ret = new JSONObject();
try{
if(!StringUtil.isEmpty(tel)){
User u = this.getUser(request.getSession());
WeixinUserInfo oldparam = new WeixinUserInfo();
oldparam.setPhone(tel);
WeixinUserInfo localWeixinUserInfo=wxPublicService.getUserInfo(oldparam);
if(u!=null&&localWeixinUserInfo!=null&&!localWeixinUserInfo.getOpenId().equals(u.getOpenId())){
log.info("checkVcode fail and phone is "+ tel + " user exsit "+localWeixinUserInfo.getOpenId());
ret.put("success", false);
ret.put("message", "电话号码已绑定其他微信");
}else{
//生成验证码
Integer code = RandomGUIDUtil.getdentifCode();
String sTotalString = HttpRequest.sendPost(" ","action=send&userid= &account= &password= &mobile=" + tel +"&content=验证码为" + code + ",请勿告知其他人,有效期为1分钟。&sendTime=&extno=");
RedisClient.setObject("vcode_"+tel,100,code);
log.info("checkVeryCode: very_code="+sTotalString+" code="+code);
//ret.put("vcode", code);
ret.put("success", true);
}
}else{
ret.put("message", "手机号不能为空");
ret.put("success", false);
}
} catch (Exception e) {
e.printStackTrace();
ret.put("success", false);
ret.put("message", e.getMessage());
log.error("messageSend error: "+e.getMessage());
}
writeJSON(response, ret.toString());
}
验证用户输入的验证码与上方法类似,将用户输入的验证码提交到后端进行比对,根据对比结果返回不同的ModelAndView跳转至不同的页面,不过在若前端进行验证码的比对可能会减小对服务器的压力。
//发送短信
@RequestMapping(value = "checkVcode")
public void checkVcode(HttpServletRequest request, HttpServletResponse response) throws IOException{
String phone = request.getParameter("phone");
String vcode = request.getParameter("vcode");
String userName=request.getParameter("userName");
User u = this.getUser(request.getSession());
JSONObject ret = new JSONObject();
try{
if(!StringUtil.isEmpty(phone)&&!StringUtil.isEmpty(vcode)){
String vcodeNum=(String) RedisClient.get("vcode_"+phone);
if((vcodeNum!=null&&vcodeNum.equals(vcode))||vcode.equals(ZongsConfig.getVal("phone.code"))){
WeixinUserInfo oldparam = new WeixinUserInfo();
oldparam.setPhone(phone);
WeixinUserInfo localWeixinUserInfo=wxPublicService.getUserInfo(oldparam);
if(localWeixinUserInfo!=null&&!localWeixinUserInfo.getOpenId().equals(u.getOpenId())){
log.info("checkVcode fail and phone is "+ phone + " user exsit "+localWeixinUserInfo.getOpenId());
ret.put("success", false);
ret.put("message", "电话号码已被使用");
}else{
//CommonConstant
u.setRealName(userName);
u.setPhone(phone);
WeixinUserInfo param = new WeixinUserInfo();
param.setOpenId(u.getOpenId());
param.setPhone(phone);
param.setRealName(userName);
wxPublicService.updateUserInfo(param);
//String userInfo = HttpRequest.sendGet(CommonConstant.BACK_SYSTEM_URL+"/jeeplus/a/weixinuser/saveUser","phone="+phone);
//log.info("create info :"+userInfo);
log.info("checkVcode success and phone is "+ phone);
ret.put("success", true);
}
}else{
ret.put("success", false);
ret.put("message", "验证码错误");
log.info("checkVcode fail and phone is "+ phone+" vcode is "+vcode +" vcodeNum is "+vcodeNum);
}
}else{
ret.put("success", false);
ret.put("message", "手机号和验证码不能为空");
log.info("checkVcode fail and phone is "+ phone+" vcode is "+vcode);
}
} catch (Exception e) {
e.printStackTrace();
ret.put("success", false);
ret.put("message", e.getMessage());
log.error("messageSend error: "+e.getMessage());
}
writeJSON(response, ret.toString());
}
本系统是基于spring mvc + mybatis的基础上进行代码编写的,相关配置及第三方类库的引入这里就不做赘述了。