您的位置:首页 > 其它

基于登录注册用ajax实现手机验证码功能

2020-06-04 08:14 465 查看

这几天做的项目接触到了用手机验证码完成一些功能,例如登录、注册、以及修改手机号码,想把流程总结出来分享给大家

基于登录发送

操作 手机号
登录 非空、格式正确、已注册

先用ajax获取框输入的手机号码提交到controller处理,部分jsp代码如下

<input type="hidden" id="u-name-reg-first" value="0" /><!--第一次输入的号码-->
<input type="text" name="key" placeholder="手机号" value=''/>
<a type="button" onclick="sendPhoneCodelogin()" titlelogin="登陆">登陆</a>

第一个框中用于双重验证号码,在点击发送信息时将第二个框中输入的号码赋值
给它,防止发送信息后改动号码
js中代码:

/**
* 发送手机验证码
*/
function sendPhoneCode() {
var mobileVal=$("#u-name-reg").val();//输入的号码
var pageFrom = "phoneLogin";//页面来源
$("#u-name-reg-first").val(mobileVal);//给第一次号码赋值
$.ajax({
url:baselocation+'/login/ajax/sendPhoneMsg',
type:'post',
dataType:'json',
data:{
"mobileVal":mobileVal,
"pageFrom":pageFrom
},
success:function(result){
if(result.success==true){
layer.msg(result.message, {icon: 1, shift: 6});
var timeTicket;
var timeNum = 60;
clearInterval(timeTicket);
/*当点击获取验证码后设置60秒计时不可点击*/
timeTicket = setInterval(function () {
if (timeNum>1){
timeNum--;
/*设置按钮不可点击*/
$(".mobile-yz-btn").addClass("mobile-yz-btn-no");
$(".mobile-yz-btn").attr("onclick","");
$(".mobile-yz-btn").text(timeNum+"秒后重新获取");
}else if (timeNum==1){
$(".mobile-yz-btn").text("点击获取验证码");
$(".mobile-yz-btn").attr("onclick","sendPhoneRegister()");
$(".mobile-yz-btn").removeClass("mobile-yz-btn-no");
timeNum = 60;
clearInterval(timeTicket);
//刷新验证码
$(".js-verify-refresh.c-green").click();
}
},1000);
}else{
layer.msg(result.message, {icon: 5, shift: 6});
}
}
})
}

消息成功发送后,提交按钮的文本框显示倒计时时间,每隔一秒触发一次事件,60秒后计时结束
在conreoller中:

//发送手机验证码
@RequestMapping("/login/ajax/sendPhoneMsg")
@ResponseBody
public Map<String,Object> sendPhoneMsg(HttpServletRequest request) throws ClientException {
Map<String,Object> json;
//获取手机号
String mobile=request.getParameter("mobileVal");
if(StringUtils.isEmpty(mobile)){
json = this.setJson(false,"号码不能为空", null);
return json;
}
if(!WebUtils.checkMobile(mobile)){
json = this.setJson(false, "号码格式错误", null);
return json;
}
//获取页面来源
String pageFrom=request.getParameter("pageFrom");
if(pageFrom!=null){
if(pageFrom.equals("register")){
String userName = request.getParameter("nameVal");
if(userService.checkUsername(userName)){
json = this.setJson(false,"该用户名已注册", null);
return json;
}
if(userService.checkMobile(mobile)){
json = this.setJson(false,"该号码已注册", null);
return json;
}
}
if(pageFrom.equals("phoneLogin")){
if(!userService.checkMobile(mobile)){
json = this.setJson(false,"该号码未注册", null);
return json;
}
}
}
json=userService.sendMobileCode(mobile,"_mobileCodeNum");
return json;
}

进行号码判空和格式处理,同时根据pageFrom参数获取页面来源,根据“登录”或“注册”页面进行号码判断。若不符合要求则无法发送信息;若通过则调用sendMobileCode方法进行信息发送

@Override
public Map<String, Object> sendMobileCode( String mobile, String cachePostfix) 				throws ClientException {

Map<String, Object> json = new HashMap<String, Object>();
String mobileCodeNum = "";
//获得验证码
mobileCodeNum = WebUtils.getRandomNum(4);//随机验证码4为数
//先删除之前的验证码缓存
String usedMobileCodeNum = (String) cache.get(mobile+"_mobileCodeNum");
cache.remove(usedMobileCodeNum);
//将验证码存入缓存
cache.set(mobile + cachePostfix, mobileCodeNum, 300);
SendSmsResponse sendSmsResponse = sendSms(mobile, mobileCodeNum);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
json.put("success", Boolean.valueOf(true));
json.put("message", "短信发送成功");
json.put("entity", null);
return json;
}
json.put("success", Boolean.valueOf(false));
json.put("message", "短信发送失败,请重试");
json.put("entity", null);

return json;
}

生成随机验证码:

/**获取k位由0-9的随机数字拼成的符串*/
public static String getRandomNum(int k){
String RandomNum = "";
for (int i=0;i<k;i++){
Random rd = new Random();
RandomNum += (int)Math.floor(rd.nextInt(9));
}
return RandomNum;
}

返回的json到ajax中,用

layer.msg(result.message, {icon: 1, shift: 6});

layer.msg(result.message, {icon: 5, shift: 6});

表示发送成功或失败

输入验证码后完成登录

点击登录条件

操作 号码 验证码
登录 非空、格式、与第一次输入相同 非空、正确

js中代码:

/**
* 根据手机号和验证码登陆
*/
function sendPhoneCodelogin() {
var mobileVal=$("#u-name-reg").val();//手机号
var mobileCode=$("#pp-randomcode-reg").val();//验证码
var firstMobile = $("#u-name-reg-first").val();//第一次输入的号码
$.ajax({
url:baselocation+'/user/ajax/phonelogin',
type:'post',
dataType:'json',
data:{
"mobileVal":mobileVal,
"mobilecode":mobileCode,
"firstMobile":firstMobile
},
success:function(result){
if(result.success==true){
window.location.href="${ctx}";
}else{
layer.msg(result.message, {icon: 5, shift: 6});
}
}
})
}

controller中代码:

/**
* 手机号登录
*/
@RequestMapping("/phonelogin")
@ResponseBody
public Map<String,Object> phoneLogin(HttpServletRequest request, HttpServletResponse response){
Map<String,Object> json = new HashMap<String,Object>();
Map<String,Object> map = new HashMap<String, Object>();
try{
//获取手机号
String mobile=request.getParameter("mobileVal");
//第一次输入的号码
String firstMobile = request.getParameter("firstMobile");
//验证码
String mobileCode=request.getParameter("mobilecode");
//从缓存提取手机验证码
String mobileCodeNum = (String) cache.get(mobile+"_mobileCodeNum");
if(StringUtils.isEmpty(mobile)){
json = this.setJson(false,"号码为空","mobile");
return json;
}
if(!WebUtils.checkMobile(mobile)){
json = this.setJson(false, "号码格式错误", null);
return json;
}
if(StringUtils.isEmpty(firstMobile) || !mobile.equals(firstMobile)){
json = this.setJson(false, "系统错误", null);
return json;
}
if(StringUtils.isEmpty(mobileCode)){
json = this.setJson(false, "验证码为空", null);
return json;
}
if (mobileCode.equals(mobileCodeNum)){
userService.phonelogin(mobile);
cache.remove(mobile+"_mobileCodeNum");
}else{
json = this.setJson(false,"验证码错误","mobile");
return json;
}
//进行登录操作
map.put("ipForget","true");
map.put("mobile",mobile);
map.put("request",request);
map.put("response",response);
map=userService.queryDoUserLoginByMobile(map);
json = this.setJson((boolean)map.get("success"), (String)map.get("message"), map);
WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, (String) map.get("uuid"), 1);
}catch (Exception e) {
this.setAjaxException(json);
logger.error("getVipInfo()---error",e);
}
return json;
}

1.若条件不符合返回相应的信息回到ajax并用

layer.msg(result.message, {icon: 5, shift: 6});

弹框显示错误信息
2.若条件符合且验证码正确,将该用户数据封装在map对象中,调用queryDoUserLoginByMobile方法,执行登录操作

/**
* 手机号登录操作
*/
public Map<String,Object> queryDoUserLoginByMobile(Map<String,Object> parameterMap) throws Exception {
Map map = new HashMap();
//--在线人数统计/限制 开始--
if(!OnlineUtil.ckeckLimit(map)) {
return map;
}
//--在线人数统计/限制 结束--
HttpServletRequest request = (HttpServletRequest)parameterMap.get("request");
HttpServletResponse response = (HttpServletResponse)parameterMap.get("response");
String ipForget = (String)parameterMap.get("ipForget");
String mobile = (String)parameterMap.get("mobile");
User user = userMapper.queryUserByEmailOrMobile(mobile);//通过号码查询用户
String account = user.getUserName();
String prefix = WebUtils.getCookie(request, UserCacheConstans.WEB_USER_LOGIN_PREFIX);
if(StringUtils.isNotEmpty(prefix)){
cache.remove(prefix);
}
if(user.getIsavalible()==2){
map.put("success",false);
map.put("message","该帐号已被禁用");
return map;
}
cache.remove(UserCacheConstans.NAME_OR_PASS_ERR_COUNT+account);
return queryDoLogin(user,ipForget,response,request);
}

User user = userMapper.queryUserByEmailOrMobile(mobile);
由于号码是唯一的,所有根据号码查询获取该用户
user.getIsavalible()
若该账号被禁用,登录失败
return queryDoLogin(user,ipForget,response,request);
若该账号不被禁用,删除之前该用户的缓存,执行登录操作

/**
* 登陆操作
*/
public Map queryDoLogin(User user, String ipForget, HttpServletResponse response, HttpServletRequest request)throws Exception{
Map map = new HashMap();
//用户密码不能让别人看到
user.setPassword("");
String uuid = RandomUtils.simpleUUID();
//当前时间戳
Long currentTimestamp=System.currentTimeMillis();
user.setLoginTimeStamp(currentTimestamp);
//当前时间
user.setLoginDatatime(new Date());
//客户端登录时间
String userLoginDatatime = URLEncoder.encode(DateUtils.format(user.getLoginDatatime(),"yyyy-MM-dd HH:mm:ss"),"UTF-8").replaceAll("\\+",  "%20");
if("true".equals(ipForget)){
//缓存用户
cache.set(uuid, user,UserCacheConstans.userTime);
//缓存用户cookie key(后台获取后,可以清除登录用户的缓存)
cache.set(UserCacheConstans.WEB_USER_LOGIN_PREFIX+user.getUserId(), uuid,UserCacheConstans.userTime);
WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, uuid, (UserCacheConstans.userTime/60/60/24));
WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGINDATATIME, userLoginDatatime , (UserCacheConstans.userTime/60/60/24));
}else{
//缓存用户
cache.set(uuid, user,86400);
//缓存用户cookie key(后台获取后,可以清除登录用户的缓存)
cache.set(UserCacheConstans.WEB_USER_LOGIN_PREFIX+user.getUserId(), uuid,UserCacheConstans.userTime);
WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, uuid, 1);
WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGINDATATIME, userLoginDatatime , 1);
}
loginCommonOperate(request,user);
// 登录时把cookie中的购物车信息加到数据库中
shopcartService.addTempShopCart(request, response, Long.valueOf(user.getUserId()));
map.put("success",true);
map.put("message","登陆成功");
map.put("user",user);
map.put("uuid",uuid);

//--在线人数统计/限制 开始--
OnlineUtil.resetOnline(request, response, user.getUserId());
//--在线人数统计/限制 结束--

return map;
}

将各种信息写入到缓存中,返回“登录成功”的信息

if(result.success==true){
window.location.href="${ctx}";
}

登录成功后,跳转到网站首页

基于注册发送

操作 账号 密码 确认密码 手机号
注册 非空、格式 、未注册 非空、格式 非空、格式、与第一次输入相同 非空、格式、未注册

jsp中:

<input id="u-name-reg" type="text" name="key" placeholder="请输入账号(英文、数字、减号或下划线且6-24个字符)" value=''  class="name-input" autocomplete="off"/>
<input id="u-password-reg" type="password" name="key" placeholder="请输入密码(包含字母、数字且不小于8位)" value='' class="bui-input"  autocomplete="off"/>
<input id="u-password-reg-again" type="password" name="key" placeholder="请确认密码" value='' style="margin:20px 0px" class="bui-input" autocomplete="off"/>
<input id="u-phone-reg" type="text" name="key" placeholder="请输入手机号码" value=''  class="name-input" autocomplete="off"/>
<input id="pp-randomcode-reg" class="name-input" placeholder="请输入验证码" name="" value="" onkeyup="$(this).next().next().next().html('');" maxlength="4" type="text">
<a class="vam ml10 disIb fl mobile-yz-btn" href="javascript:void(0)" onclick="sendPhoneCode()" title="">点击获取验证码</a>
<a class="loginBtn" type="button" onclick="Register()" title="注 册">注册</a>

1.可以同上面所说的“登录”一样将获取到的值通过ajax发送到controller中处理,再将结果返回
2.可以在js的function()中获取各个框中输入的值作判断处理,若不符合要求则无法跳到controller中处理,本例采用这种方式

//发送验证码
function sendPhoneCode() {
var pageFrom = "register";
var mobileVal=$("#u-phone-reg").val();

var nameVal = $("#u-name-reg").val();
if (nameVal == null || nameVal == "") {
layer.msg("请输入账号", {icon: 5, shift: 6});
return;
}
if (!isNaN(nameVal)) {
layer.msg("账号不能全为数字", {icon: 5, shift: 6});
return;
}
if (nameVal.length < 6 || nameVal.length > 24) {
layer.msg("账号长度为6-24个字符", {icon: 5, shift: 6});
return;
}
if (usernameRegex.test(nameVal) == false) {//账号格式
layer.msg("账号仅支持英文、数字、减号或下划线", {icon: 5, shift: 6});
return;
}
var password = $("#u-password-reg").val();
if (password == null || password == "") {
layer.msg("请输入密码", {icon: 5, shift: 6});
return;
}
password = encrypt(password);
var passwordAgain = $("#u-password-reg-again").val();
if (passwordAgain == null || passwordAgain == "") {
layer.msg("请确认密码", {icon: 5, shift: 6});
return;
}
passwordAgain = encrypt(passwordAgain);
if (password!=passwordAgain) {
layer.msg("两次密码不一致", {icon: 5, shift: 6});
return;
}
$.ajax({
url:baselocation+'/login/ajax/sendPhoneMsg',
type:'post',
dataType:'json',
data:{
"nameVal":nameVal,
"mobileVal":mobileVal,
"pageFrom":pageFrom
},
success:function(result){
if(result.success==true){
layer.msg("短信发送成功", {icon: 1, shift: 6});
var timeTicket;
var timeNum = 60;
//$("#phoneClick").css("visibility","hidden");
// $("#recoverPhoneClick").css("visibility","visible");
clearInterval(timeTicket);
/*当点击获取验证码后设置60秒计时不可点击*/
timeTicket = setInterval(function () {
if (timeNum>1){
timeNum--;
/*设置按钮不可点击*/
$(".mobile-yz-btn").addClass("mobile-yz-btn-no");
$(".mobile-yz-btn").attr("onclick","");
$(".mobile-yz-btn").text(timeNum+"秒后重新获取");
}else if (timeNum==1){
$(".mobile-yz-btn").text("点击获取验证码");
$(".mobile-yz-btn").attr("onclick","sendPhoneRegister()");
$(".mobile-yz-btn").removeClass("mobile-yz-btn-no");
timeNum = 60;

clearInterval(timeTicket);

//刷新验证码
$(".js-verify-refresh.c-green").click();
}
},1000);
}else{
layer.msg(result.message, {icon: 5, shift: 6});
}
}
})
}

其余代码跟登录相似,只是pageFrom的值不同,这样controller中才会根据不同页面对“用户名”和“手机号”作判断。若该账号或手机号已注册,则无法发送验证码,相比在点击“注册”时对之作判断,可以减少很多“无用”信息

if(pageFrom.equals("register")){
String userName = request.getParameter("nameVal");
if(userService.checkUsername(userName)){
json = this.setJson(false,"该用户名已注册", null);
return json;
}
if(userService.checkMobile(mobile)){
json = this.setJson(false,"该号码已注册", null);
return json;
}
}

输入验证码后完成注册

点击注册条件

操作 号码 验证码
注册 非空、格式、未注册、与发送验证码的号码相同 非空、正确

其余逻辑均与“登录”时相似,注册成功后,登录该用户,显示主页面

Tips:本人第一篇博客,若有不足之处,欢迎大家予以斧正。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: