10-SpringMVC 使用拦截器实现登录认证

1.原理概念

1.应用场景

假如你写了一个网站, 为了避免别人直接输入网址,跳过登录环节就直接进入需要账号登录的页面, 比如用户个人中心页面,这个时候就可以使用拦截器来进行一个登录认证。

2.执行原理

①首先配置拦截器, 进入登录页面和账号密码提交的请求是直接放行的(不需要账号登录的页面也直接放行)。
②执行账号密码提交请求时, 若用户名、密码匹配正确, 则将用户名存储在HttpSession中。
③对需要登录账号才能访问的页面请求在拦截器的preHandle方法中执行判断, 若能读取到存储在HttpSession的用户名, 则说明已经登录成功过了, 进行放行。否则进行拦截, 并重定向到登录页面。
④HttpSession中的数据默认30分钟不访问便清除, 所以进入网站后长时间不进行相关操作,登录信息会失效,需要重新登录,保障账号安全。

注意:以上只是以最简单的逻辑实现了登录认证,这里仅作学习而已,真正安全可靠的登录认证要比这复杂的多。

2.代码实现

项目结构
10-SpringMVC 使用拦截器实现登录认证_第1张图片
pom.xml


<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>

3.运行测试

1.不登录直接访问success.html页面

在这里插入图片描述
被重定向到登录页
10-SpringMVC 使用拦截器实现登录认证_第2张图片

2.输入错误用户名或密码登录

10-SpringMVC 使用拦截器实现登录认证_第3张图片
被重定向到登录页
10-SpringMVC 使用拦截器实现登录认证_第4张图片

3.输入正确用户名或密码登录

10-SpringMVC 使用拦截器实现登录认证_第5张图片
登录成功
10-SpringMVC 使用拦截器实现登录认证_第6张图片
接下由于HttpSession中已经存储了登录信息, 所以直接输入success.html的网址http://localhost:8080/springMVC/success也能直接访问了, 短时间内无需二次登录。

你可能感兴趣的:(SpringMVC入门,mvc,java-ee,spring)