SpringBoot Session接口验证实现流程详解

目录
  • 添加pom.xml
  • 创建简单的测试接口
  • 使用过滤器实现
  • 使用拦截器实现

需求:只有用户登录成功后,才能访问其它接口,否则提示需要进行登录

项目仓库地址:https://gitee.com/aiw-nine/springboot_session_verify

添加pom.xml

新建Spring Boot(2.7.2)项目,添加如下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aiw</groupId>
    <artifactId>waimai</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>waimai</name>
    <description>waimai</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

创建简单的测试接口

package com.aiw.springboot_session_verify.controller;
import com.aiw.springboot_session_verify.entity.User;
import com.aiw.springboot_session_verify.response.R;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
@RestController
@RequestMapping("/user")
public class UserController {
    /**
     * 登录,此处只做简单测试
     *
     * @param user
     * @param request
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public R<User> login(@RequestBody User user, HttpServletRequest request) {
    	// 此处应该和数据库进行交互判断,为做测试,简单写死
        if (Objects.equals(user.getId(), 1) && Objects.equals(user.getName(), "Aiw")) {
            // 登录成功,将id存入session并返回登录成功结果
            request.getSession().setAttribute("user", user.getId());
            request.getSession().setMaxInactiveInterval(1800);  // 设置session失效时间为30分钟
            return R.success("登录成功", user);
        }
        return R.fail("登录失败");
    }
    /**
     * 退出登录
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    public R<String> logout(HttpServletRequest request) {
        request.getSession().removeAttribute("user");
        return R.success("退出成功");
    }
    /**
     * 此处做测试,看用户在未登录时,能否访问到此接口
     *
     * @return
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public R<String> index() {
        return R.success("首页,访问成功");
    }
}

使用过滤器实现

创建LoginCheckFilter.java类,实现Filter接口

package com.aiw.springboot_session_verify.filter;
import com.aiw.springboot_session_verify.response.R;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
/**
 * 检查用户是否已经完成登录(方式一:过滤器)
 * 需要在启动类上加上@ServletComponentScan注解,这样才会扫描@WebFilter注解
 */
@Slf4j
@WebFilter
public class LoginCheckFilter implements Filter {
    // 路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        log.info("拦截到的请求:{}", request.getRequestURI());
        // 1、获取本次请求的URI
        String requestURI = request.getRequestURI();
        // 定义不需要处理的请求路径
        String[] urls = new String[]{"/user/login", "/user/logout"};
        // 2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);
        // 3、如果不需要处理,则直接放行
        if (check) {
            log.info("本次请求{}不需要处理", requestURI);
            filterChain.doFilter(request, response);
            return;
        }
        // 4、判断登录状态,如果已登录,则直接放行
        if (Objects.nonNull(request.getSession().getAttribute("user"))) {
            log.info("用户已登录,用户id为:{}", request.getSession().getAttribute("user"));
            filterChain.doFilter(request, response);
            return;
        }
        // 5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        log.info("用户未登录");
        response.setContentType("application/json; charset=utf-8");
        // 1、使用Fastjson(默认过滤null值)
        response.getWriter().write(JSON.toJSONString(R.error("未登录")));
        // 2、使用默认的Jackson,此处关于Jackson配置的相关属性会失效(即若在配置文件中配置过滤null值,这里返回时不会过滤)
        // response.getWriter().write(new ObjectMapper().writeValueAsString(R.error("未登录")));
        return;
    }
    /**
     * 路径匹配,检查本次请求是否需要放行
     *
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls, String requestURI) {
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) return true;
        }
        return false;
    }
}

修改启动类

package com.aiw.springboot_session_verify;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class SpringbootSessionVerifyApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootSessionVerifyApplication.class, args);
    }
}

启动项目,使用ApiPost进行接口测试。首先在未登录状态下,访问/user/index接口

可以看到在未登录时,访问其它接口会失败

此时先进行登录,访问/user/login接口

再次访问/user/index接口

即登录成功后,可以成功访问该接口;为保证后续操作,此处再访问/user/logout接口,删除后端的session

使用拦截器实现

创建LoginCheckInterceptor.java类,实现HandlerInterceptor接口

package com.aiw.springboot_session_verify.interceptor;
import com.aiw.springboot_session_verify.response.R;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;
/**
 * 检查用户是否已经完成登录(方式二:拦截器)
 * 需要在实现WebMvcConfigurer接口的配置类中重写addInterceptors方法,将拦截器注册到容器,并指定拦截规则
 */
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取请求
        log.info("拦截的请求:{}", request.getRequestURI());
        //2.判断用户是否登录
        HttpSession session = request.getSession();
        // 若存在,则放行
        if (Objects.nonNull(session.getAttribute("user"))) return true;
        //拦截住,并给前端页面返回未登录信息,以输出流的方式,json格式返回
        response.setContentType("application/json; charset=utf-8");
        // 1、使用Fastjson(默认过滤null值)
        response.getWriter().write(JSON.toJSONString(R.error("未登录")));
        // 2、使用默认的Jackson,在配置文件中关于Jackson配置的相关属性会失效
        //response.getWriter().write(new ObjectMapper().writeValueAsString(R.error("未登录")));
        return false;
    }
}

注册拦截器,新建配置类WebConfig.java,实现WebMvcConfigurer接口

package com.aiw.springboot_session_verify.config;
import com.aiw.springboot_session_verify.interceptor.LoginCheckInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * 注册拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginCheckInterceptor())
                .addPathPatterns("/**")
                // 排除的请求路径
                .excludePathPatterns("/user/login", "/user/logout");
    }
}

注释掉LoginCheckFilter.java类,再注释掉启动类上的@ServletComponentScan注解,防止过滤器的干扰,启动项目。首先在未登录状态下,访问/user/index接口

进行登录,访问/user/login接口

再次访问/user/index接口

至此,全部完成,当然后期可以使用Spring Boot+JWT实现接口验证

到此这篇关于SpringBoot Session接口验证实现流程详解的文章就介绍到这了,更多相关SpringBoot Session接口验证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot 整合 Spring-Session 实现分布式会话项目实战

    目录 一.配置及开发 二.测试 三.Spring-Session 的缺点 文章参考: Spring 提供了处理分布式会话的解决方案:Spring-Session.Spring-Session 提供了对Redis.MongoDB.MySQL 等常用存储的支持,Spring-Session 提供与 HttpSession 的透明整合,这意味着开发人员可以使用 Spring-Session 支持的实现方式,切换 HttpSession 至 Spring-Session.本文采用 Redis 作为第三方

  • SpringBoot下实现session保持方式

    目录 相关概念 1.HTTP是无状态协议 2.哪些方法可以实现有状态连接 3.Session是由Web服务器端(Tomcat)维护的 实现方法 实现方法 实现原理 实现代码 如何插入一段漂亮的代码片 总结 相关概念 1.HTTP是无状态协议 无状态是指协议对于事务处理没有记忆功能.缺少状态意味着,假如后面的处理需要前面的信息,则前面的信息必须重传,这样可能导致每次连接传送的数据量增大.另一方面,在服务器不需要前面信息时,应答就较快.直观地说,就是每个请求都是独立的,与前面的请求和后面的请求都是没

  • Spring Session(分布式Session共享)实现示例

    目录 HttpSession的实现流程 Tomcat中的HttpSession实现 使用 导入依赖 编辑配置文件 编辑启动类 编辑控制器 @EnableRedisHttpSession注解属性 redisNamespace maxInactiveIntervalInSeconds flushMode saveMode cleanupCron Spring Session保存在Redis中的数据 spring:session:sessions:唯一值 spring:session:sessions

  • 详解SpringBoot中@SessionAttributes的使用

    目录 简介 概述 代码 后端代码 前端代码 测试 简介 说明 本文介绍SpringBoot中@SessionAttributes的用法. 概述 在默认情况下,ModelMap中的属性作用域是request级别,也就是说,当本次请求结束后,ModelMap 中的属性将销毁.如果希望在多个请求中共享ModelMap中的属性,必须将其属性转存到session 中,这样 ModelMap 的属性才可以被跨请求访问. Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 sessi

  • SpringBoot2.x设置Session失效时间及失效跳转方式

    目录 设置Session失效时间及失效跳转 Session失效后如何跳转到Session失效地址 设置Session失效的几种方式 如果是1.5.6版本 还可以设置 设置Session失效时间及失效跳转 #Session超时时间设置,单位是秒,默认是30分钟  server.servlet.session.timeout=10 然而并没有什么用,因为SpringBoot在TomcatServletWebServerFactory代码中写了这个     private long getSessio

  • springboot普通类中如何获取session问题

    目录 Spring中普通类获取session 项目中日志功能 解决方案 SpringBoot中使用session 基础知识 在 Spring Boot中使用 总结 Spring中普通类获取session 项目中日志功能 记录所有通过后台操作的记录,记录项有 时间.操作员.功能模块.操作内容 写了一个基于注解方式的aop,实现日志功能 使用shiro的话可以直接获取到用户的token,然后获取到用户登录信息 可是项目中没有使用token,使用的是session绑定登录信息,需要在@Aspect中获

  • SpringBoot中HttpSessionListener的简单使用方式

    目录 HttpSessionListener的使用方式 session监听实现类 controller调用 注册HttpSessionListener失效原因 问题描述 原因 HttpSessionListener的使用方式 session监听实现类 import org.springframework.stereotype.Component; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpS

  • SpringBoot整合SpringSession实现分布式登录详情

    目录 Session 共享 为什么服务器 A 登录后,请求发到服务器 B,不认识该用户? 解决方案 SpringBoot整合SpringSession实现分布式登录 Session 共享 比如两个域名: aaa.yupi.com bbb.yupi.com 如果要共享 cookie,可以种一个更高层的公共域名,比如 yupi.com 为什么服务器 A 登录后,请求发到服务器 B,不认识该用户? 用户在 A 登录,所以 session(用户登录信息)存在了 A 上 结果请求 B 时,B 没有用户信息

  • SpringBoot3整合MyBatis出现异常:Property 'sqlSessionFactory'or 'sqlSessionTemplate' are required

    目录 交代一下背景 问题出现 问题排查 解决问题:需要升级版本 总结 SpringBoot3整合MyBatis报错:Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required 遇到了一个 Spring Boot 3 整合 MyBatis 的问题,然后解决了.当然,这其实不是个大问题,只是自己编码时遇到了,然后总结总结分享一下.如果有遇到类似问题的,可以参考一下. 交代一下背景 最近在熟悉 Spring Boot 3 版本的代

  • SpringBoot集成redis与session实现分布式单点登录

    目录 单点登录 SSO(Single Sign On) 什么是单点登录? 实现方式 开发技术 单点登录实现流程 实现案例 看效果 前言: 由于考虑到cookie的安全性问题,就有了下面这个版本的sso 单点登录 SSO(Single Sign On) 什么是单点登录? 单点登录的英文名叫做:Single Sign On(简称SSO),指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的系统.简而言之,多个系统,统一登陆. 我们可以这样理解,在一个服务模块登录后,其他模块无

随机推荐