鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > java > >

web登录添加用户+IP限制方法

来源:互联网 作者:佚名 时间:2022-07-19 11:31
font color=#999AAA /font @TOC hr style= border:solid; width:100px; height:1px; color=#000000 size=1 前言 font color=#999AAA 因为项目需要限制同一个用户的同一个IP只能登录一个,并且7天后要重新登录,所以考虑

<font color=#999AAA >

</font>

@TOC

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

前言

<font color=#999AAA >因为项目需要限制同一个用户的同一个IP只能登录一个,并且7天后要重新登录,所以考虑用redis实现。项目使用springmvc+shiro+vue。</font>

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

一、流程及图

1.简易流程图如下:

在这里插入图片描述

1.登录页面:

在这里插入图片描述

一、前端:

1.表单提交

<el-form id="app" :model="loginForm" :rules="rules" ref="loginForm" label-width="70px" label-position="right" @keyup.native.enter="login"> <div class="login-page"> <div class="dialog"> <div class="info"> <el-form-item label="用户名" prop="username"> <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input> </el-form-item> <el-form-item prop="code" > <el-row :gutter="20"> <el-col :span="15"> <el-input v-model="loginForm.code" :disabled="sendCodeBtn.writedisabled" placeholder="短信验证码"> <i slot="prefix" class="el-icon-tickets"></i> </el-input> </el-col> <el-col :span="8"> <el-button :type="sendCodeBtn.type" @click="sendLoginSms" :disabled="sendCodeBtn.disabled">{{sendCodeBtn.content}}</el-button> </el-col> </el-row> </el-form-item> <div class="remembers"> <el-form-item label="" prop="rememberMe"> <el-checkbox v-model="loginForm.rememberMe">记住我</el-checkbox> </el-form-item> </div> </div> <div class="btndiv"> <el-button type="primary" style="width:100%;" @click="login">登录</el-button> </div> </div> </div> </el-form>

2.登录方法

login : function() {// 登录 debugger; // 获取实例对象 var _this = this; if(_this.isLoginValidate){ this.getLogin(); }else { this.$refs['loginForm'].validate((valid) => { if (valid) { this.getLogin(); } }) } }, getLogin(){ var _this = this; _this.send = _this.send + 1; axios.get(_this.loginUrl, {params : _this.loginForm}).then(function (response) { debugger; // 获取响应数据 var r = response.data; debugger; console.log(r); if (r.sysUser || r.success) { debugger; window.location.href = "${urlPath }index.do"; _this.sendCodeBtn.disabled = true; _this.sendCodeBtn.type = "info"; } else { // 提示错误信息 if(r.message){ _this.$message.error(r.message); } _this.sendCodeBtn.writedisabled = false; if(r.code == "5"){ _this.sendCodeBtn.disabled = false; _this.sendCodeBtn.type = "primary"; _this.isLoginValidate = false; } } }).catch(function (error) {// 请求数据处理失败 // 提示错误信息 _this.$message.error("请再点击一次“登录”按钮确认登录"); }) },

3.发送短信方法

sendLoginSms : function(){ debugger; var _this = this; _this.sendCodeBtn.disabled = true; _this.sendCodeBtn.type = "info"; axios.get(_this.sendLoginSmsUrl,{params : _this.loginForm}).then(function (response) { debugger; // 获取响应数据 var r = response.data; if(r.success){ _this.sendCodeBtn.writedisabled = false; _this.$message.success(r.message); var time = 60; _this.sendSmsInterval = window.setInterval(function () { if(time > 0){ _this.sendCodeBtn.content = time--; }else { window.clearInterval(_this.sendSmsInterval); _this.sendCodeBtn.content = "发送"; _this.sendCodeBtn.disabled = false; _this.sendCodeBtn.type = "primary"; } },1000) }else { _this.$message.error(r.message); _this.sendCodeBtn.disabled = false; _this.sendCodeBtn.type = "primary"; if(r.code == "6"){ _this.sendCodeBtn.disabled = true; _this.sendCodeBtn.type = "info"; } } }).catch(function (error) { _this.$message.error("服务器异常!") }) }

4.发送短信倒计时

mounted(){ this.time = this.countDown }

三、login控制

1.login登录接口

/** * @Description web端登陆 * @Param [req] **/ @RequestMapping("/login") @ResponseBody public Result login(HttpServletRequest req) { // 获取登录异常类名 String className = (String) req.getAttribute("shiroLoginFailure"); // 登录异常处理 if (UnknownAccountException.class.getName().equals(className) || IncorrectCredentialsException.class.getName().equals(className)) { return Results.opError("用户名或密码错误!"); } if (DisabledAccountException.class.getName().equals(className)) { return Results.opError("该用户被禁用!"); } String code = req.getParameter("code"); String username = req.getParameter("username"); if(StringUtils.isBlank(username) ){ return Results.error("请输入用户名及密码"); } SysUser sysUser = sysUserService.selectOne( SQLHelper.build(SysUser.class).mustEq("username",username).geEntityWrapper()); String ip = IPUtil.getIp(req); if(sysUser==null){ return Results.error("该用户不存在,请填写正确的用户名"); } byte[] ipKeyByte = RedisUtil.getKeyByte(Constants.LOGIN_IP, username+ip); if(StringUtils.isNotBlank(code)) { String phone = sysUser.getTelephone(); if(StringUtils.isBlank(phone)){ logger.error("手机号码不存在"); return Results.error("该用户手机号码不存在,请联系管理员"); } byte[] codeKeyByte = RedisUtil.getKeyByte(Constants.LOGIN_CODE, phone); String redisCode = RedisUtil.getRedisString(codeKeyByte); if(StringUtils.isNotBlank(redisCode)){ if(code.equals(redisCode)){ RedisUtil.addRedisString(username,ipKeyByte,LOGIN_IP_SECONDS); return Results.opOk(); }else { return Results.error("请输入正确的短信验证码"); } }else { return Results.error("5","短信验证码已过期,请重新发送"); } }else { String ipStr = RedisUtil.getRedisString(ipKeyByte); if (StringUtils.isEmpty(ipStr)) { return Results.error("5","请验证短信码后才能登陆"); }else { return Results.opOk(); } } }

2.发送短信接口

为了之后其他测试模块复用

/** * @Description web端登陆短信验证 * @Param [req] **/ @RequestMapping("/sendLoginSms") @ResponseBody public Result sendLoginSms(HttpServletRequest req) { try{ String username = req.getParameter("username"); if(StringUtils.isBlank(username) ){ return Results.error("请输入用户名及密码"); } SysUser sysUser = sysUserService.selectOne( SQLHelper.build(SysUser.class).eq("username",username).geEntityWrapper()); String phone = null; if(sysUser !=null){ phone = sysUser.getTelephone(); }else { logger.error("该用户不存在"); return Results.error("该用户不存在,请填写正确的用户名"); } if(StringUtils.isBlank(phone)){ logger.error("手机号码不存在"); return Results.error("该用户手机号码不存在,请联系管理员"); } String ip = IPUtil.getIp(req); byte[] codeCountByte = RedisUtil.getKeyByte(Constants.LOGIN_Code_COUNT_PREFIX, phone + ip); String redisCodeCount = RedisUtil.getRedisString(codeCountByte); Integer count = redisCodeCount == null ? 1 : Integer.valueOf(redisCodeCount) + 1; if (count > 4 && count <= 8){ RedisUtil.addRedisString(count.toString(),codeCountByte,60*60); return Results.error("操作太过频繁,请1小时后再试"); } if(count > 8 && count < 12){ RedisUtil.addRedisString(count.toString(),codeCountByte,60*60*4); return Results.error("操作太过频繁,请4小时后再试"); } if(count >= 12){ RedisUtil.addRedisString(count.toString(),codeCountByte,60*60*24); return Results.error("6","操作太过频繁,请24小时后再试"); } RedisUtil.addRedisString(count.toString(),codeCountByte,LOGIN_CODE_COUNT_SECONDS); byte[] codeKeyByte = RedisUtil.getKeyByte(Constants.LOGIN_CODE_PREFIX, phone); String redisCode = RedisUtil.getRedisString(codeKeyByte); if(StringUtils.isNotBlank(redisCode)){ return Results.error("验证码已发送,请不要频繁操作"); } String code = RandomStringUtils.randomNumeric(6); if(messageService.sendLoginSms(code, phone)){ RedisUtil.addRedisString(code,codeKeyByte,LOGIN_CODE_SECONDS); return Results.ok("短信验证码发送成功,5分钟内有效",null); } } catch (Exception e) { logger.error("短信发送失败",e); } return Results.error("发送失败,请稍后重试"); }

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

随心所往,看见未来。Follow your heart,see night!<br/>欢迎点赞、关注、留言,一起学习、交流!

上一篇:ngnix+tomcat转发、负载均衡
下一篇:没有了
网友评论
<