假如你写了一个网站, 为了避免别人直接输入网址,跳过登录环节就直接进入需要账号登录的页面, 比如用户个人中心页面,这个时候就可以使用拦截器来进行一个登录认证。
①首先配置拦截器, 进入登录页面和账号密码提交的请求是直接放行的(不需要账号登录的页面也直接放行)。
②执行账号密码提交请求时, 若用户名、密码匹配正确, 则将用户名存储在HttpSession中。
③对需要登录账号才能访问的页面请求在拦截器的preHandle方法中执行判断, 若能读取到存储在HttpSession的用户名, 则说明已经登录成功过了, 进行放行。否则进行拦截, 并重定向到登录页面。
④HttpSession中的数据默认30分钟不访问便清除, 所以进入网站后长时间不进行相关操作,登录信息会失效,需要重新登录,保障账号安全。
注意:以上只是以最简单的逻辑实现了登录认证,这里仅作学习而已,真正安全可靠的登录认证要比这复杂的多。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.limigroupId>
<artifactId>test01-HelloWorldartifactId>
<version>1.0-SNAPSHOTversion>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>6source>
<target>6target>
configuration>
plugin>
plugins>
build>
<packaging>warpackaging>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.15.RELEASEversion>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>4.0.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleaf-spring5artifactId>
<version>3.0.12.RELEASEversion>
dependency>
dependencies>
project>
springMVC.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.limi"/>
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
bean>
property>
bean>
property>
bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
<property name="supportedMediaTypes">
<list>
<value>text/htmlvalue>
<value>application/jsonvalue>
list>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/index"/>
<mvc:exclude-mapping path="/login"/>
<ref bean="firstInterceptor">ref>
mvc:interceptor>
mvc:interceptors>
beans>
LoginController
package com.limi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@GetMapping("/index")
public String index(){
return "index";
}
@PostMapping("/login")
public String login(HttpSession session, String username, String password){
System.out.println("username:"+username+" password:"+password);
if("andy".equals(username)&&"123456".equals(password)) { //账号密码匹配成功
session.setAttribute("username", username);
return "redirect:/success";
}
return "redirect:/index";
}
@GetMapping("/success")
public ModelAndView test1(HttpSession session){
System.out.println("======执行控制器中方法success======");
String name = (String)session.getAttribute("username");
ModelAndView mv = new ModelAndView();
mv.addObject("name", name);
mv.setViewName("success");
return mv;
}
}
FirstInterceptor
package com.limi.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Component
public class FirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("==========FirstInterceptor preHandle==========");
HttpSession session = request.getSession();
if(session.getAttribute("username")!=null) //已登录
return true;//放行
else{
//未登录, 重定向到登录页
response.sendRedirect(request.getContextPath()+"/index");
}
return false;//拦截
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("==========FirstInterceptor postHandle==========");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("==========FirstInterceptor afterCompletion==========");
}
}
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springMVCservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springMVC.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springMVCservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
index.html
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>请输入用户名和密码登录!h1>
<form th:action="@{/login}" method="post">
用户名<input type="text" name="username"><br>
密码<input type="text" name="password"><br>
<input type="submit" value="登录">
form>
body>
html>
success.html
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>login success!h1>
<p>欢迎<span th:text="${name}">的来临!span>p>
body>
html>
登录成功
接下由于HttpSession中已经存储了登录信息, 所以直接输入success.html的网址http://localhost:8080/springMVC/success也能直接访问了, 短时间内无需二次登录。