第三章. 业务功能开发--用户登录安全退出
1. 用户登录
需求:
用户在登录页面,输入用户名和密码,点击"登录"按钮或者回车,完成用户登录的功能.
*用户名和密码不能为空
*用户名或者密码错误,用户已过期,用户状态被锁定,ip受限 都不能登录成功
*登录成功之后,所有业务页面显示当前用户的名称
*实现10天记住密码
*登录成功之后,跳转到业务主页面
*登录失败,页面不跳转,提示信息
-
编写UserController类
通过前端传入的变量,读取数据库返回user对象,通过对象中的信息对上述的条件做出判断并对上述需求创合适的session
然后将返回的信息放到object对象中返回出去,然后通过login.jsp中的信息做出判断,是否跳转到业务的控制台;
package com.bjpowernode.crm.settings.web.controller; import com.bjpowernode.crm.commons.contants.Contants; import com.bjpowernode.crm.commons.domain.ReturnObject; import com.bjpowernode.crm.commons.utils.DateUtils; import com.bjpowernode.crm.settings.domain.User; import com.bjpowernode.crm.settings.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; @Controller public class UserController { @Autowired private UserService userService; /** * url要和controller方法处理完请求之后,响应信息返回的页面的资源目录保持一致 */ @RequestMapping("/settings/qx/user/toLogin.do") public String toLogin(){ //请求转发到登录页面 return "settings/qx/user/login"; } @RequestMapping("/settings/qx/user/login.do") public @ResponseBody Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpServletResponse response, HttpSession session){ //封装参数 Map<String,Object> map=new HashMap<>(); map.put("loginAct",loginAct); map.put("loginPwd",loginPwd); //调用service层方法,查询用户 User user=userService.queryUserByLoginActAndPwd(map); //根据查询结果,生成响应信息 ReturnObject returnObject=new ReturnObject(); if(user==null){ //登录失败,用户名或者密码错误 returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL); returnObject.setMessage("用户名或者密码错误"); }else{//进一步判断账号是否合法 //user.getExpireTime() //2019-10-20 // new Date() //2020-09-10 if(DateUtils.formateDateTime(new Date()).compareTo(user.getExpireTime())>0){ //登录失败,账号已过期 returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL); returnObject.setMessage("账号已过期"); }else if("0".equals(user.getLockState())){ //登录失败,状态被锁定 returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL); returnObject.setMessage("状态被锁定"); }else if(!user.getAllowIps().contains(request.getRemoteAddr())){ //登录失败,ip受限 returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL); returnObject.setMessage("ip受限"); }else{ //登录成功 returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS); //把user保存到session中 session.setAttribute(Contants.SESSION_USER,user); //如果需要记住密码,则往外写cookie if("true".equals(isRemPwd)){ Cookie c1=new Cookie("loginAct",user.getLoginAct()); c1.setMaxAge(10*24*60*60); response.addCookie(c1); Cookie c2=new Cookie("loginPwd",user.getLoginPwd()); c2.setMaxAge(10*24*60*60); response.addCookie(c2); }else{ //把没有过期cookie删除 Cookie c1=new Cookie("loginAct","1"); c1.setMaxAge(0); response.addCookie(c1); Cookie c2=new Cookie("loginPwd","1"); c2.setMaxAge(0); response.addCookie(c2); } } } return returnObject; } @RequestMapping("/settings/qx/user/logout.do") public String logout(HttpServletResponse response,HttpSession session){ //清空cookie Cookie c1=new Cookie("loginAct","1"); c1.setMaxAge(0); response.addCookie(c1); Cookie c2=new Cookie("loginPwd","1"); c2.setMaxAge(0); response.addCookie(c2); //销毁session session.invalidate(); //跳转到首页 return "redirect:/";//借助springmvc来重定向,response.sendRedirect("/crm/"); } }
-
其中我的数据库中的user信息如下,一直报错,检查页面的返回数据得出,我的数据库密码和数据名称错了,下次注意。
-
在index.jsp 中更具返回的信息做出判断:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/"; %> <html> <head> <base href="<%=basePath%>"> <meta charset="UTF-8"> <link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script> <script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script> <script type="text/javascript"> $(function () { //给整个浏览器窗口添加键盘按下事件 $(window).keydown(function (e) { //如果按的是回车键,则提交登录请求 if(e.keyCode==13){ $("#loginBtn").click(); } }); //给"登录"按钮添加单击事件 $("#loginBtn").click(function () { //收集参数 var loginAct=$.trim($("#loginAct").val()); var loginPwd=$.trim($("#loginPwd").val()); var isRemPwd=$("#isRemPwd").prop("checked"); //表单验证 if(loginAct==""){ alert("用户名不能为空"); return; } if(loginPwd==""){ alert("密码不能为空"); return; } //显示正在验证 $("#msg").text("正在努力验证...."); //发送请求 $.ajax({ url:'settings/qx/user/login.do', data:{ loginAct:loginAct, loginPwd:loginPwd, isRemPwd:isRemPwd }, type:'post', dataType:'json', success:function (data) { if(data.code=="1"){ //跳转到业务主页面 window.location.href="workbench/index.do"; }else{ //提示信息 $("#msg").text(data.message); } }, beforeSend:function () {//当ajax向后台发送请求之前,会自动执行本函数; //该函数的返回值能够决定ajax是否真正向后台发送请求: //如果该函数返回true,则ajax会真正向后台发送请求;否则,如果该函数返回false,则ajax放弃向后台发送请求。 $("#msg").text("正在努力验证...."); return true; } }); }); }); </script> </head> <body> <div style="position: absolute; top: 0px; left: 0px; width: 60%;"> <img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;"> </div> <div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;"> <div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">©2019 动力节点</span></div> </div> <div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5"> <div style="position: absolute; top: 0px; right: 60px;"> <div class="page-header"> <h1>登录</h1> </div> <form action="workbench/index.html" class="form-horizontal" role="form"> <div class="form-group form-group-lg"> <div style="width: 350px;"> <input class="form-control" id="loginAct" type="text" value="${cookie.loginAct.value}" placeholder="用户名"> </div> <div style="width: 350px; position: relative;top: 20px;"> <input class="form-control" id="loginPwd" type="password" value="${cookie.loginPwd.value}" placeholder="密码"> </div> <div class="checkbox" style="position: relative;top: 30px; left: 10px;"> <label> <c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}"> <input type="checkbox" id="isRemPwd" checked> </c:if> <c:if test="${empty cookie.loginAct or empty cookie.loginPwd}"> <input type="checkbox" id="isRemPwd"> </c:if> 十天内免登录 </label> <span id="msg" style="color: red"></span> </div> <button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button> </div> </form> </div> </div> </body> </html>
2安全退出
需求如下:
用户在任意的业务页面,点击"退出"按钮,弹出确认退出的模态窗口;用户在确认退出的模态窗口,点击"确定"按钮,完成安全退出的功能.
*安全退出,清空cookie,销毁session
*退出完成之后,跳转到首页