zoukankan      html  css  js  c++  java
  • SSM 拦截器验证权限和登录与注销的实现

    拦截器的作用在于,比如我们输入 xxx.com/admin 发起请求进入 网站后台或者其他后台页面。我们的拦截器会在 Controller  调用之前进行拦截,至于什么拦截,由我们来写。比如,判断用户是否登录(可以通过 session 判断),如果没有登录,我们让它跳转到登录页面。

    转载 https://liuyanzhao.com/6300.html 

    一、拦截器的基本使用

    1、新建一个 拦截器

    SecurityInterceptor.java

     
    1. package com.liuyanzhao.blog.Interceptor;
    2. import org.springframework.web.servlet.HandlerInterceptor;
    3. import org.springframework.web.servlet.ModelAndView;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. public class SecurityInterceptor implements HandlerInterceptor {
    7.     @Override
    8.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
    9.         System.out.println("SecurityInterceptor...preHandle...");
    10.         //这里可以根据session的用户来判断角色的权限,根据权限来转发不同的页面
    11.         if(request.getSession().getAttribute("userId") == null) {
    12.             request.getRequestDispatcher("/login").forward(request,response);
    13.             return false;
    14.         }
    15.         return true;
    16.     }
    17.     @Override
    18.     public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    19.     }
    20.     @Override
    21.     public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    22.     }
    23. }

    判断是否有 userId 这个session,如果没有(或者过期了)转发到登录页面

    2、配置 springmvc.xml

    通过使用 mvc:interceptors 标签来声明需要加入到SpringMVC拦截器链中的拦截器。

     
    1. <mvc:interceptors>
    2.       <mvc:interceptor>
    3.           <mvc:mapping path="/admin"/>
    4.           <bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
    5.       </mvc:interceptor>
    6.       <mvc:interceptor>
    7.           <mvc:mapping path="/admin/**"/>
    8.           <bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
    9.       </mvc:interceptor>
    10.   </mvc:interceptors>

    只需两步,我们已经能成功拦截  /admin 和其其前缀的如 /admin/article 等其他所有路径啦。

    二、登录实现

    登录主要是验证该用户是否存在,密码是否正确。然后添加 session 和页面跳转

    1、登录表单

    login.jsp

     
    1. <%
    2.          String username = "";
    3.          String password = "";
    4.          //获取当前站点的所有Cookie
    5.          Cookie[] cookies = request.getCookies();
    6.          for (int i = 0; i cookies.length; i++) {//对cookies中的数据进行遍历,找到用户名、密码的数据
    7.              if ("username".equals(cookies[i].getName())) {
    8.                     username = cookies[i].getValue();
    9.              } else if ("password".equals(cookies[i].getName())) {
    10.                  password = cookies[i].getValue();
    11.              }
    12.          }
    13. %>
    14.     <form name="loginForm" id="loginForm"  method="post">
    15.                 <input type="text" name="username" id="user_login"
    16.                            class="input" value="<%=username%>" size="20" required/></label>
    17.                 <input type="password" name="password" id="user_pass"
    18.                            class="input" value="<%=password%>" size="20" required/>
    19.                  <input name="rememberme" type="checkbox" id="rememberme" value="1" /> 记住密码
    20.                 <input type="button" name="wp-submit" id="submit-btn" class="button button-primary button-large" value="登录" />
    21.     </form>

    为了代码简洁,这里去掉了多余的标签和属性。我这里是扒了 wordpress 的登录页面,这里也用到了 cookie 。

    SSM博客实战(9)-拦截器验证权限和登录与注销的实现

    注意:这里的 form 表单里没有 action 属性,最终发送数据通过 ajax 。同样,也没有 submit 按钮,为了防止 ajax+form+submit 导致 success 里无法页面跳转。

    2、js 代码

     
    1. <%--登录验证--%>
    2.  $("#submit-btn").click(function () {
    3.      var user = $("#user_login").val();
    4.      var password = $("#user_pass").val();
    5.      if(user=="") {
    6.          alert("用户名不可为空!");
    7.      } else if(password==""){
    8.          alert("密码不可为空!");
    9.      } else {
    10.          $.ajax({
    11.              async: false,//同步,待请求完毕后再执行后面的代码
    12.              type: "POST",
    13.              url: '${pageContext.request.contextPath}/loginVerify',
    14.              contentType: "application/x-www-form-urlencoded; charset=utf-8",
    15.              data: $("#loginForm").serialize(),
    16.              dataType: "json",
    17.              success: function (data) {
    18.                  if(data.code==0) {
    19.                      alert(data.msg);
    20.                  } else {
    21.                      window.location.href="${pageContext.request.contextPath}/admin";
    22.                  }
    23.              },
    24.              error: function () {
    25.                  alert("数据获取失败")
    26.              }
    27.          })
    28.      }
    29.  })

    这里 ajax 使用同步,防止出现后台没有返回值,就执行了后面的js代码,进而出现 ajax 执行 error:function() 里的代码。数据类型使用 json,当然也可以使用 text,只不过 text 只能 返回普通的字符串。

    最后,如果验证通过,将跳转到 xxx.com/admin 页面(当然后台需要加入session,否则拦截器会拦截)。

    3、控制器代码

     
    1. //登录页面显示
    2.     @RequestMapping("/login")
    3.     public ModelAndView loginView() {
    4.         ModelAndView modelAndView = new ModelAndView();
    5.         modelAndView.setViewName("/Admin/login");
    6.         return modelAndView;
    7.     }
    8.     //登录验证
    9.     @RequestMapping(value = "/loginVerify",method = RequestMethod.POST)
    10.     @ResponseBody
    11.     public String loginVerify(HttpServletRequest request, HttpServletResponse response) throws Exception {
    12.         Map<String, Object> map = new HashMap<String, Object>();
    13.         String username = request.getParameter("username");
    14.         String password = request.getParameter("password");
    15.         String rememberme = request.getParameter("rememberme");
    16.         UserCustom userCustom = userService.getUserByNameOrEmail(username);
    17.         if(userCustom==null) {
    18.             map.put("code",0);
    19.             map.put("msg","用户名无效!");
    20.         } else if(!userCustom.getUserPass().equals(password)) {
    21.             map.put("code",0);
    22.             map.put("msg","密码错误!");
    23.         } else {
    24.             //登录成功
    25.             map.put("code",1);
    26.             map.put("msg","");
    27.             //添加session
    28.             request.getSession().setAttribute("user", userCustom);
    29.             //添加cookie
    30.             if(rememberme!=null) {
    31.                 //创建两个Cookie对象
    32.                 Cookie nameCookie = new Cookie("username", username);
    33.                 //设置Cookie的有效期为3天
    34.                 nameCookie.setMaxAge(60 * 60 * 24 * 3);
    35.                 Cookie pwdCookie = new Cookie("password", password);
    36.                 pwdCookie.setMaxAge(60 * 60 * 24 * 3);
    37.                 response.addCookie(nameCookie);
    38.                 response.addCookie(pwdCookie);
    39.             }
    40.         }
    41.         String result = new JSONObject(map).toString();
    42.         return result;
    43.     }

    这里登录验证方法内,getUserByNameOrEmail() 方法用来从数据库里查找是否有该用户(用户名或者邮箱)。如果有,而且密码正确,添加一条 session,要和拦截器里写的一致哦。并将信息添加到 Map 中,然后转成 JSON 数据,这里需要导入 对应JSON 的jar 哦。

     
    1. <dependency>
    2.   <groupId>org.json</groupId>
    3.   <artifactId>json</artifactId>
    4.   <version>20170516</version>
    5. </dependency>

    4、Service 和 DAO

    这里就不贴 Service 和 Dao 的代码了,主要就是根据 字符串查找用户的操作啦。

    三、注销实现

    注销就比较简单了,清除 session 就行了。

    1、jsp 页面

     
    1. <href="${pageContext.request.contextPath}/admin/logout">退了</a>

    2、控制器代码

     
    1. //退出登录
    2.    @RequestMapping(value = "/admin/logout")
    3.    public String logout(HttpSession session) throws Exception {
    4.        session.removeAttribute("userId");
    5.        session.invalidate();
    6.        return "redirect:/login";
    7.    }
  • 相关阅读:
    linux卸载mysql
    【Linux/Oracle】ORA-00031:标记要终止的会话 解决
    linux上 oracle数据库的密码过期-解决
    SYSTEM表空间满,解决方法
    Oracle 撤回已经提交的事务
    关于MySQL取不到数据
    解决mysql只能通过localhost而不能使用本机ip访问的问题
    linux 卸载php,史上最详情
    关于支付宝免密代扣申请(全),小程序,公众号,php
    mcrypt_module_open 微信小程序 php7不能使用的问题
  • 原文地址:https://www.cnblogs.com/yachao1120/p/10997681.html
Copyright © 2011-2022 走看看