登录拦截
-
OK,比较常见的就是Spring Security安全框架,为的就是保护接口不被直接调用,只有通过登录后,才可以调用项目内的接口,这里呢,我讲一种比较常见的用法,利用session和拦截器解决这个问题
我们一步一步分析一下,
-
1、首先我们要拦截所有的请求,这里要注意的是要对登录等接口进行放行
-
2、要对拦截下的所有请求进行处理,判断用户是否有权限调用,才可以进行放行
-
3、有了登录,那么对应的就要退出登录,
基本就这三块,细说一下流程
-
1、拦截器的配置
-
web.xml
:这没有太多的要求,重点在SpringMVC中进行配置,这里分析一个比较全面web.xml文件 -
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!--指定页面加载的初始页面 --> <!-- <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> --> <!-- 加载spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 解决跨域问题 --> <!-- CORS --> <filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowOrigin</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, POST, HEAD, PUT, DELETE,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Access-Control-Allow-Origin</param-value> </init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>Set-Cookie</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 解决post乱码 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <!-- <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> --> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- springmvc的前端控制器 --> <servlet> <servlet-name>aiot-manager</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>aiot-manager</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 解决日志输出问题,存放 --> <context-param> <param-name>webAppRootKey</param-name> <param-value>aiot.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/resource/log4j.properties</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <!--当系统出现404错误,跳转到页面nopage.html --> <error-page> <error-code>404</error-code> <location>/index.html</location> </error-page> <!--会话超时配置,单位分钟 --> <session-config> <session-timeout>360</session-timeout> </session-config> </web-app>
-
-
对应的SpringMVC中进行配置:
-
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Springmvc的配置文件 ,包含网站跳转逻辑的控制,配置 --> <!-- <context:component-scan base-package="com.alone.controller" annotation-config="false"> 只扫描控制器 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> --> <!-- 第一步:开启springioc 自动扫描注解 --> <context:component-scan base-package="com.xx.controller" /> <!-- 拦截器,拦截所有的请求 这里是重点 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.aiot.service.session.LoginInterceptor" /> </mvc:interceptor> </mvc:interceptors> <!-- 配置视图解析器,方便页面返回 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/html/"></property> <property name="suffix" value=".html"></property> </bean> <!-- 资源映射,这里的作用就是为了方便jsp页面中前缀文件的获取,这里后期可以改一下,根据前段要求来更改位置 --> <mvc:resources location="/WEB-INF/css/" mapping="/css/**"></mvc:resources> <mvc:resources location="/WEB-INF/js/" mapping="/js/**"></mvc:resources> <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射, 配置一个基于注解的定制的WebBindingInitializer,解决日期转换问题,方法级别的处理器映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="cacheSeconds" value="0" /> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --> </list> </property> <property name="webBindingInitializer"> <bean class="com.aiot.util.MyWebBinding" /> </property> </bean> <!-- 两个标准配置 --> <!-- 将springmvc不能处理的请求交给tomcat --> <mvc:default-servlet-handler /> <!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax..映射动态请求 --> <mvc:annotation-driven />
-
-
拦截器对应的类
-
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import com.aiot.util.ConstantAiot; import com.aiot.util.LoggerUtil; /** * @ClassName: LoginInterceptor * @Description: 该类用于拦截类,拦截所有的请求,进行校验,判断用户是否在session中有信息, * @author boway * @date 2018年8月1日 * */ public class LoginInterceptor implements HandlerInterceptor { private static final String[] URI_ACTION = {"login"}; @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { String url = request.getRequestURI(); LoggerUtil.info("访问路径 " + url); for (String urls : URI_ACTION) { if (url.contains(urls)) { return true; } } System.out.println(request.getSession().getAttribute(ConstantAiot.USER_CONTEXT)); if(request.getSession().getAttribute(ConstantAiot.USER_CONTEXT)!=null) { return true; } request.getRequestDispatcher("/login.html").forward(request, response); //这是跳转至请求 // arg1.sendRedirect("user/login"); return false; } }
-
-
这里提供一个Session的工具类,方便使用
-
package com.aiot.service.session; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Component; import com.aiot.entity.UserInfo; import com.aiot.util.ConstantAiot; /** * @ClassName: BaseController * @Description: 该类用于将用户信息存放或清除session * @author boway * @date 2018年8月1日 * */ @Component public class BaseSession { /** * @Title: setSessionUser * @Description: 将数据放入session中,并设置过期时间 * @param @param request * @param @param user 参数 * @return void 返回类型 * @throws */ public void setSessionUser(HttpServletRequest request,UserInfo user) { request.getSession().setMaxInactiveInterval(100 * 60); request.getSession().setAttribute(ConstantAiot.USER_CONTEXT, user); } public UserInfo getSessionUser(HttpServletRequest request) { return (UserInfo)request.getSession().getAttribute(ConstantAiot.USER_CONTEXT); } public void removeSessionUser(HttpServletRequest request) { request.getSession().removeAttribute(ConstantAiot.USER_CONTEXT);//清空session信息 request.getSession().invalidate();//清除 session 中的所有信息 //return (UserInfo)request.getSession().getAttribute(ConstantAiot.USER_CONTEXT); } }
-
-
下面就是controller类了
-
/** * @ClassName: UserController * @Description: 用户登录controller类,现用于用户登录 * @author lenovo * @date 2018年7月9日 */ @Controller @RequestMapping("/user") public class UserLoginController { private static Logger logger = Logger.getLogger(UserLoginController.class); @Autowired private UserLoginService userLoginService; @Autowired private BaseSession baseSession; /** * @throws Exception * @Title: loginUser * @Description: 用户登录验证对应的controller层方法 * @param @param aiotUserT * @param @return 参数 * @return String 返回类型 * @throws */ @RequestMapping(value="/login",method=RequestMethod.POST) @ResponseBody public Msg loginUser(HttpServletRequest request,UserInfo userInfo){ //这里判断为空,建议使用JSR303进行校验,我这就简单示范 if (userInfo.getUsername() == null || userInfo.getPassword() == null) { return Msg.fail().setMsg("参数为空登录失败"); } logger.info("UserController.loginUser() start aiotUserT" + userInfo); try { //这里是对密码进行加密操作,我这里使用的AES加密,建议也使用这种加密方式 String aesDecrypt = AESUtil.aesEncrypt(userInfo.getPassword()); userInfo.setPassword(aesDecrypt); } catch (Exception e) { return Msg.fail().setMsg("登录异常"); } Msg checkUser = userLoginService.checkUser(userInfo); if (checkUser.getCode() == 200) { //这里是校验数据是否存在,如果存在就放入到session中,要注意的要将密码清空 UserInfo object = (UserInfo) checkUser.getExtend().get("userInfo"); baseSession.setSessionUser(request,object); } logger.info("UserController.loginUser() end loginMsg " + checkUser); return checkUser; } /** * @Title: loginUserOut * @Description: 退出登录 * @param @param request * @param @param response * @param @return 参数 * @return Msg 返回类型 * @throws */ @RequestMapping(value="/loginOut",method=RequestMethod.POST) @ResponseBody public Msg loginUserOut(HttpServletRequest request,HttpServletResponse response){ logger.info("UserController.loginUser() start loginUserOut"); UserInfo user=baseSession.getSessionUser(request); System.out.println("user " + user); baseSession.setSessionUser(request, null); return Msg.success().setMsg("退出登录成功"); } }
-
-
代码到这里就OK了,
版权声明:本文为weixin_41905099原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。