SprinMVC 拦截器验证权限和登录与注销的实现
2018-01-02 17:27
736 查看
本文将介绍通过拦截器验证权限和后台登录与注销。
拦截器的作用在于,比如我们输入 xxx.com/admin 发起请求进入 网站后台或者其他后台页面。我们的拦截器会在 Controller 调用之前进行拦截,至于什么拦截,由我们来写。比如,判断用户是否登录(可以通过 session 判断),如果没有登录,我们让它跳转到登录页面。
SecurityInterceptor.java
package com.liuyanzhao.blog.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
System.out.println("SecurityInterceptor...preHandle...");
//这里可以根据session的用户来判断角色的权限,根据权限来转发不同的页面
if(request.getSession().getAttribute("userId") == null) {
request.getRequestDispatcher("/login").forward(request,response);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
判断是否有 userId 这个session,如果没有(或者过期了)转发到登录页面
2、配置 springmvc.xml
通过使用 mvc:interceptors 标签来声明需要加入到SpringMVC拦截器链中的拦截器。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/admin"/>
<bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
只需两步,我们已经能成功拦截 /admin 和其其前缀的如 /admin/article 等其他所有路径啦。
1、登录表单
login.jsp
<%
String username = "";
String password = "";
//获取当前站点的所有Cookie
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {//对cookies中的数据进行遍历,找到用户名、密码的数据
if ("username".equals(cookies[i].getName())) {
username = cookies[i].getValue();
} else if ("password".equals(cookies[i].getName())) {
password = cookies[i].getValue();
}
}
%>
<form name="loginForm" id="loginForm" method="post">
<input type="text" name="username" id="user_login"
class="input" value="<%=username%>" size="20" required/></label>
<input type="password" name="password" id="user_pass"
class="input" value="<%=password%>" size="20" required/>
<input name="rememberme" type="checkbox" id="rememberme" value="1" /> 记住密码
<input type="button" name="wp-submit" id="submit-btn" class="button button-primary button-large" value="登录" />
</form>
为了代码简洁,这里去掉了多余的标签和属性。我这里是扒了 wordpress 的登录页面,这里也用到了 cookie 。
注意:这里的 form 表单里没有 action 属性,最终发送数据通过 ajax 。同样,也没有 submit 按钮,为了防止 ajax+form+submit 导致 success 里无法页面跳转。
2、js 代码
<%--登录验证--%>
$("#submit-btn").click(function () {
var user = $("#user_login").val();
var password = $("#user_pass").val();
if(user=="") {
alert("用户名不可为空!");
} else if(password==""){
alert("密码不可为空!");
} else {
$.ajax({
async: false,//同步,待请求完毕后再执行后面的代码
type: "POST",
url: '${pageContext.request.contextPath}/loginVerify',
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: $("#loginForm").serialize(),
dataType: "json",
success: function (data) {
if(data.code==0) {
alert(data.msg);
} else {
window.location.href="${pageContext.request.contextPath}/admin";
}
},
error: function () {
alert("数据获取失败")
}
})
}
})
这里 ajax 使用同步,防止出现后台没有返回值,就执行了后面的js代码,进而出现 ajax 执行 error:function() 里的代码。数据类型使用 json,当然也可以使用 text,只不过 text 只能 返回普通的字符串。
最后,如果验证通过,将跳转到 xxx.com/admin 页面(当然后台需要加入session,否则拦截器会拦截)。
3、控制器代码
//登录页面显示
@RequestMapping("/login")
public ModelAndView loginView() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/Admin/login");
return modelAndView;
}
//登录验证
@RequestMapping(value = "/loginVerify",method = RequestMethod.POST)
@ResponseBody
public String loginVerify(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
String username = request.getParameter("username");
String password = request.getParameter("password");
String rememberme = request.getParameter("rememberme");
UserCustom userCustom = userService.getUserByNameOrEmail(username);
if(userCustom==null) {
map.put("code",0);
map.put("msg","用户名无效!");
} else if(!userCustom.getUserPass().equals(password)) {
map.put("code",0);
map.put("msg","密码错误!");
} else {
//登录成功
map.put("code",1);
map.put("msg","");
//添加session
request.getSession().setAttribute("user", userCustom);
//添加cookie
if(rememberme!=null) {
//创建两个Cookie对象
Cookie nameCookie = new Cookie("username", username);
//设置Cookie的有效期为3天
nameCookie.setMaxAge(60 * 60 * 24 * 3);
Cookie pwdCookie = new Cookie("password", password);
pwdCookie.setMaxAge(60 * 60 * 24 * 3);
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
}
String result = new JSONObject(map).toString();
return result;
}
这里登录验证方法内,getUserByNameOrEmail() 方法用来从数据库里查找是否有该用户(用户名或者邮箱)。如果有,而且密码正确,添加一条 session,要和拦截器里写的一致哦。并将信息添加到 Map 中,然后转成 JSON 数据,这里需要导入 对应JSON 的jar 哦。
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
是
4、Service 和 DAO
这里就不贴 Service 和 Dao 的代码了,主要就是根据 字符串查找用户的操作啦。
1、jsp 页面
<a href="${pageContext.request.contextPath}/admin/logout">退了</a>
2、控制器代码
//退出登录
@RequestMapping(value = "/admin/logout")
public String logout(HttpSession session) throws Exception {
session.removeAttribute("userId");
session.invalidate();
return "redirect:/login";
}
本来准备录制GIF效果图,但是苦于图片太大就不上传了。
拦截器的作用在于,比如我们输入 xxx.com/admin 发起请求进入 网站后台或者其他后台页面。我们的拦截器会在 Controller 调用之前进行拦截,至于什么拦截,由我们来写。比如,判断用户是否登录(可以通过 session 判断),如果没有登录,我们让它跳转到登录页面。
一、拦截器的基本使用
1、新建一个 拦截器SecurityInterceptor.java
package com.liuyanzhao.blog.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
System.out.println("SecurityInterceptor...preHandle...");
//这里可以根据session的用户来判断角色的权限,根据权限来转发不同的页面
if(request.getSession().getAttribute("userId") == null) {
request.getRequestDispatcher("/login").forward(request,response);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
判断是否有 userId 这个session,如果没有(或者过期了)转发到登录页面
2、配置 springmvc.xml
通过使用 mvc:interceptors 标签来声明需要加入到SpringMVC拦截器链中的拦截器。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/admin"/>
<bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<bean class="com.liuyanzhao.blog.Interceptor.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
只需两步,我们已经能成功拦截 /admin 和其其前缀的如 /admin/article 等其他所有路径啦。
二、登录实现
登录主要是验证该用户是否存在,密码是否正确。然后添加 session 和页面跳转1、登录表单
login.jsp
<%
String username = "";
String password = "";
//获取当前站点的所有Cookie
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {//对cookies中的数据进行遍历,找到用户名、密码的数据
if ("username".equals(cookies[i].getName())) {
username = cookies[i].getValue();
} else if ("password".equals(cookies[i].getName())) {
password = cookies[i].getValue();
}
}
%>
<form name="loginForm" id="loginForm" method="post">
<input type="text" name="username" id="user_login"
class="input" value="<%=username%>" size="20" required/></label>
<input type="password" name="password" id="user_pass"
class="input" value="<%=password%>" size="20" required/>
<input name="rememberme" type="checkbox" id="rememberme" value="1" /> 记住密码
<input type="button" name="wp-submit" id="submit-btn" class="button button-primary button-large" value="登录" />
</form>
为了代码简洁,这里去掉了多余的标签和属性。我这里是扒了 wordpress 的登录页面,这里也用到了 cookie 。
注意:这里的 form 表单里没有 action 属性,最终发送数据通过 ajax 。同样,也没有 submit 按钮,为了防止 ajax+form+submit 导致 success 里无法页面跳转。
2、js 代码
<%--登录验证--%>
$("#submit-btn").click(function () {
var user = $("#user_login").val();
var password = $("#user_pass").val();
if(user=="") {
alert("用户名不可为空!");
} else if(password==""){
alert("密码不可为空!");
} else {
$.ajax({
async: false,//同步,待请求完毕后再执行后面的代码
type: "POST",
url: '${pageContext.request.contextPath}/loginVerify',
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: $("#loginForm").serialize(),
dataType: "json",
success: function (data) {
if(data.code==0) {
alert(data.msg);
} else {
window.location.href="${pageContext.request.contextPath}/admin";
}
},
error: function () {
alert("数据获取失败")
}
})
}
})
这里 ajax 使用同步,防止出现后台没有返回值,就执行了后面的js代码,进而出现 ajax 执行 error:function() 里的代码。数据类型使用 json,当然也可以使用 text,只不过 text 只能 返回普通的字符串。
最后,如果验证通过,将跳转到 xxx.com/admin 页面(当然后台需要加入session,否则拦截器会拦截)。
3、控制器代码
//登录页面显示
@RequestMapping("/login")
public ModelAndView loginView() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/Admin/login");
return modelAndView;
}
//登录验证
@RequestMapping(value = "/loginVerify",method = RequestMethod.POST)
@ResponseBody
public String loginVerify(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
String username = request.getParameter("username");
String password = request.getParameter("password");
String rememberme = request.getParameter("rememberme");
UserCustom userCustom = userService.getUserByNameOrEmail(username);
if(userCustom==null) {
map.put("code",0);
map.put("msg","用户名无效!");
} else if(!userCustom.getUserPass().equals(password)) {
map.put("code",0);
map.put("msg","密码错误!");
} else {
//登录成功
map.put("code",1);
map.put("msg","");
//添加session
request.getSession().setAttribute("user", userCustom);
//添加cookie
if(rememberme!=null) {
//创建两个Cookie对象
Cookie nameCookie = new Cookie("username", username);
//设置Cookie的有效期为3天
nameCookie.setMaxAge(60 * 60 * 24 * 3);
Cookie pwdCookie = new Cookie("password", password);
pwdCookie.setMaxAge(60 * 60 * 24 * 3);
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
}
String result = new JSONObject(map).toString();
return result;
}
这里登录验证方法内,getUserByNameOrEmail() 方法用来从数据库里查找是否有该用户(用户名或者邮箱)。如果有,而且密码正确,添加一条 session,要和拦截器里写的一致哦。并将信息添加到 Map 中,然后转成 JSON 数据,这里需要导入 对应JSON 的jar 哦。
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
是
4、Service 和 DAO
这里就不贴 Service 和 Dao 的代码了,主要就是根据 字符串查找用户的操作啦。
三、注销实现
注销就比较简单了,清除 session 就行了。1、jsp 页面
<a href="${pageContext.request.contextPath}/admin/logout">退了</a>
2、控制器代码
//退出登录
@RequestMapping(value = "/admin/logout")
public String logout(HttpSession session) throws Exception {
session.removeAttribute("userId");
session.invalidate();
return "redirect:/login";
}
本来准备录制GIF效果图,但是苦于图片太大就不上传了。
相关文章推荐
- 在MVC中添加拦截器实现登录后的权限验证
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程
- SSH学习——Struts2拦截器实现登录权限验证
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)
- Struts2拦截器 实现未登录拦截和权限控制
- struts2获取当前方法的Action的Url 登录验证拦截器实现
- shiro框架---关于用户登录和权限验证功能的实现步骤(六)
- 过滤器和拦截器的比较及未登录用户权限限制的实现
- spring boot配置shiro安全框架及用户登录权限验证实现
- 自定义拦截器实现验证登录
- 构建基于CXF的WebService服务(3)-- 利用拦截器实现权限验证
- SpringMVC拦截器(实现登录验证拦截器)
- struts2 实现登录拦截器和验证方法
- 过滤器和拦截器的比较及未登录用户权限限制的实现
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- 构建基于CXF的WebService服务(3)-- 利用拦截器实现权限验证
- shiro框架---关于用户登录和权限验证功能的实现步骤(三)
- 过滤器和拦截器的比较及未登录用户权限限制的实现(ZHUAN)
- Shiro 整合SpringMVC 并实现权限管理,登录和注销
- Shiro 整合SpringMVC 并且实现权限管理,登录和注销