Springboot中登录后关于cookie和session拦截问题的案例分析

一、前言

1、简单的登录验证可以通过Session或者Cookie实现。
2、每次登录的时候都要进数据库校验下账户名和密码,只是加了cookie 或session验证后;比如登录页面A,登录成功后进入页面B,若此时cookie过期,在页面B中新的请求url到页面c,系统会让它回到初始的登录页面。(类似单点登录sso(single sign on))。
3、另外,无论基于Session还是Cookie的登录验证,都需要对HandlerInteceptor进行配置,增加对URL的拦截过滤机制。

二、利用Cookie进行登录验证

1、配置拦截器代码如下:

public class CookiendSessionInterceptor implements HandlerInterceptor {  

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  log.debug("进入拦截器");
  Cookie[] cookies = request.getCookies();
  if(cookies!=null && cookies.length>0){
   for(Cookie cookie:cookies) {
     log.debug("cookie===for遍历"+cookie.getName());
     if (StringUtils.equalsIgnoreCase(cookie.getName(), "isLogin")) {
      log.debug("有cookie ---isLogin,并且cookie还没过期...");
      //遍历cookie如果找到登录状态则返回true继续执行原来请求url到controller中的方法
      return true;
        }
      }
     }
   log.debug("没有cookie-----cookie时间可能到期,重定向到登录页面后请重新登录。。。");
   response.sendRedirect("index.html");
   //返回false,不执行原来controller的方法
   return false;  }  

 @Override
 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  }
 @Override
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  } 

}

2、在Springboot中拦截的请求不管是配置监听器(定义一个类实现一个接口HttpSessionListener )、过滤器、拦截器,都要配置如下此类实现一个接口中的两个方法。
代码如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {
// 这个方法是用来配置静态资源的,比如html,js,css,等等
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
 } 

 // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
@Override
public void addInterceptors(InterceptorRegistry registry) {
//addPathPatterns("/**") 表示拦截所有的请求
//excludePathPatterns("/firstLogin","/zhuce");设置白名单,就是拦截器不拦截。首次输入账号密码登录和注册不用拦截!
//登录页面在拦截器配置中配置的是排除路径,可以看到即使放行了,还是会进入prehandle,但是不会执行任何操作。
registry.addInterceptor(new CookiendSessionInterceptor()).addPathPatterns("/**").excludePathPatterns("/",
                          "/**/login",
                          "/**/*.html",
                          "/**/*.js",
                          "/**/*.css",
                          "/**/*.jpg");
 } 

 }

3.前台登录页面index.html(我把这个html放在静态资源了,也让拦截器放行了此路由url)
前端测试就是一个简单的form表单提交

<!--测试cookie和sessionid-->
<form action="/login" method="post">
 账号:<input type="text" name="name1" placeholder="请输入账号"><br>
 密码:<input type="password" name="pass1" placeholder="请输入密码"><br>
 <input type="submit" value="登录">
</form>

4、后台控制层Controller业务逻辑:登录页面index.html,登录成功后 loginSuccess.html。
在loginSuccess.html中可提交表单进入次页demo.html,也可点击“退出登录”后台清除没有超时的cookie,并且回到初始登录页面。

@Controller
@Slf4j
@RequestMapping(value = "/")
public class TestCookieAndSessionController {
@Autowired  JdbcTemplate jdbcTemplate;
/**  * 首次登录,输入账号和密码,数据库验证无误后,响应返回你设置的cookie。再次输入账号密码登录或者首次登录后再请求下一个页面,就会在请求头中携带cookie,  * 前提是cookie没有过期。  * 此url请求方法不管是首次登录还是第n次登录,拦截器都不会拦截。  * 但是每次(首次或者第N次)登录都要进行,数据库查询验证账号和密码。  * 做这个目的是如果登录页面A,登录成功后进页面B,页面B有链接进页面C,如果cookie超时,重新回到登录页面A。(类似单点登录)  */  

@PostMapping(value = "login")
public String test(HttpServletRequest request, HttpServletResponse response, @RequestParam("name1")String name,@RequestParam("pass1")String pass) throws Exception{
 try {
 Map<String, Object> result= jdbcTemplate.queryForMap("select * from userinfo where name=? and password=?", new Object[]{name, pass});
  if(result==null || result.size()==0){
   log.debug("账号或者密码不正确或者此人账号没有注册");
   throw new Exception("账号或者密码不正确或者此人账号没有注册!");
  }else{
   log.debug("查询满足条数----"+result);
   Cookie cookie = new Cookie("isLogin", "success");
   cookie.setMaxAge(30);
   cookie.setPath("/");
   response.addCookie(cookie);
   request.setAttribute("isLogin", name);
   log.debug("首次登录,查询数据库用户名和密码无误,登录成功,设置cookie成功");
   return "loginSuccess";    }
 } catch (DataAccessException e) {
   e.printStackTrace();
   return "error1";
  }
 } 

/**测试登录成功后页面loginSuccess ,进入次页demo.html*/
@PostMapping(value = "sub")
public String test() throws Exception{
 return "demo";
 }
/** 能进到此方法中,cookie一定没有过期。因为拦截器在前面已经判断力。过期,拦截器重定向到登录页面。过期退出登录,清空cookie。*/
@RequestMapping(value = "exit",method = RequestMethod.POST)
public String exit(HttpServletRequest request,HttpServletResponse response) throws Exception{
 Cookie[] cookies = request.getCookies();
 for(Cookie cookie:cookies){
 if("isLogin".equalsIgnoreCase(cookie.getName())){
  log.debug("退出登录时,cookie还没过期,清空cookie");
  cookie.setMaxAge(0);
  cookie.setValue(null);
  cookie.setPath("/");
  response.addCookie(cookie);
  break;
  }
  }
 //重定向到登录页面
 return "redirect:index.html";
  } 

}

5、效果演示:
①在登录“localhost:8082”输入账号登录页面登录:

②拦截器我设置了放行/login,所以请求直接进Controller相应的方法中:
日志信息如下:

下图可以看出,浏览器有些自带的不止一个cookie,这里不要管它们。

③在loginSuccess.html,进入次页demo.html。cookie没有过期顺利进入demo.html,并且/sub方法经过拦截器(此请求请求头中携带cookie)。
过期的话直接回到登录页面(这里不展示了)

④在loginSuccess.html点击“退出登录”,后台清除我设置的没过期的cookie=isLogin,回到登录页面。

三、利用Session进行登录验证

1、修改拦截器配置略微修改下:

Interceptor也略微修改下:还是上面的preHandle方法中:

2.核心
前端我就不展示了,就是一个form表单action="login1"
后台代码如下:

/**利用session进行登录验证*/
@RequestMapping(value = "login1",method = RequestMethod.POST)
public String testSession(HttpServletRequest request,
       HttpServletResponse response,
       @RequestParam("name1")String name,
       @RequestParam("pass1")String pass) throws Exception{
 try {
 Map<String, Object> result= jdbcTemplate.queryForMap("select * from userinfo where name=? and password=?", new Object[]{name, pass});
  if(result!=null && result.size()>0){
  String requestURI = request.getRequestURI();
  log.debug("此次请求的url:{}",requestURI);
  HttpSession session = request.getSession();
  log.debug("session="+session+"session.getId()="+session.getId()+"session.getMaxInactiveInterval()="+session.getMaxInactiveInterval());
  session.setAttribute("isLogin1", "true1");
  }
 } catch (DataAccessException e) {
  e.printStackTrace();
  return "error1";
 }
 return "loginSuccess";
 } 

 //登出,移除登录状态并重定向的登录页
@RequestMapping(value = "/exit1", method = RequestMethod.POST)
public String loginOut(HttpServletRequest request) {
 request.getSession().removeAttribute("isLogin1");
 log.debug("进入exit1方法,移除isLogin1");
 return "redirect:index.html";
 }
 }

日志如下:可以看见springboot内置的tomcat中sessionid就是请求头中的jsessionid,而且默认时间1800秒(30分钟)。
我也不清楚什么进入拦截器2次,因为我login1设置放行了,肯定不会进入拦截器。可能是什么静态别的什么资源吧。

session.getId()=F88CF6850CD575DFB3560C3AA7BEC89F==下图的JSESSIONID

//点击退出登录,请求退出url的请求头还是携带JSESSIONID,除非浏览器关掉才消失。(该session设置的属性isLogin1移除了,session在不关浏览器情况下或者超过默认时间30分钟后,session才会自动清除!)

四、完结

到此这篇关于Springboot中登录后关于cookie和session拦截案例的文章就介绍到这了,更多相关Springboot登录关于cookie和session拦截内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘. 刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)...,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑. 我面临的第一个问题是跨域,浏览器控制台直接报CORS,

  • 解决前后端分离 vue+springboot 跨域 session+cookie失效问题

    环境: 前端 vue ip地址:192.168.1.205 后端 springboot2.0 ip地址:192.168.1.217 主要开发后端. 问题: 首先登陆成功时将用户存在session中,后续请求在将用户从session中取出检查.后续请求取出的用户都为null. 解决过程: 首先发现sessionID不一致,导致每一次都是新的会话,当然不可能存在用户了.然后发现cookie浏览器不能自动保存,服务器响应set-cookie了 搜索问题,发现跨域,服务器响应的setCookie浏览器无

  • SpringBoot+Vue+Redis实现单点登录(一处登录另一处退出登录)

    一.需求 实现用户在浏览器登录后,跳转到其他页面,当用户在其它地方又登录时,前面用户登录的页面退出登录(列如qq挤号那种方式) 二.实现思路 用户在前端填写用户信息登录后,后台接收数据先去数据库进行判断,如果登录成功,创建map集合,以用户id为键,token为值,先通过当前登录用户的id去获取token,如果token存在说明该用户已经登录过,调用redis以token为键删除上个用户的信息,调用方法生成新token,并将token存入map集合,将用户信息存入redis,并将token存入c

  • SpringBoot + Spring Security 基本使用及个性化登录配置详解

    Spring Security 基本介绍 这里就不对Spring Security进行过多的介绍了,具体的可以参考官方文档 我就只说下SpringSecurity核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) 基本环境搭建 这里我们以SpringBoot作为项目的基本框架,我这里使用的是maven的方式来进行的包管理,所以这里先给出集成Spring Security的方式 <dependencies> ... <dependency> <groupI

  • 基于springboot实现整合shiro实现登录认证以及授权过程解析

    这篇文章主要介绍了基于springboot实现整合shiro实现登录认证以及授权过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.添加shiro的依赖 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web- starter</artifactId> <version&g

  • Springboot中登录后关于cookie和session拦截问题的案例分析

    一.前言 1.简单的登录验证可以通过Session或者Cookie实现. 2.每次登录的时候都要进数据库校验下账户名和密码,只是加了cookie 或session验证后:比如登录页面A,登录成功后进入页面B,若此时cookie过期,在页面B中新的请求url到页面c,系统会让它回到初始的登录页面.(类似单点登录sso(single sign on)). 3.另外,无论基于Session还是Cookie的登录验证,都需要对HandlerInteceptor进行配置,增加对URL的拦截过滤机制. 二.

  • Laravel 登录后清空COOKIE的操作方法

    需求 在Laravel 登陆立即清空保存的COOKIE数组 实现 # Http/Controllers/Auth/LoginController.php public function redirectTo() { // 设置为登陆成功 session session()->put('show-login-success', 1); // 订阅内容 $logs = request()->cookie('subscribe'); if ($logs) { $subscribe = new Sub

  • 详解springboot中redis的使用和分布式session共享问题

    对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题. 实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat.Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中. 本文旨在

  • PHP cookie与session会话基本用法实例分析

    本文实例讲述了PHP cookie与session会话基本用法.分享给大家供大家参考,具体如下: cookie即是传统的会话控制,由于要存储的信息是保存在客户端的,所以安全系数较低,而session会话控制是将要存储的信息保存在服务器上的,所以相对于cookie安全系数较高. 不论是在使用cookie方式存储,还是session方式存储在使用存储的函数之前都不能有输出语句,否则会产生一个e级错误 使用cookie的存储的方式 setcookie('cookie_name','cookie_val

  • php中cookie与session的区别点总结

    本教程操作环境:windows7系统.PHP7.1版.DELL G3电脑 无论是在系统运维还是 PHP 开发人员的面试中,经常会被问到 Session 和 Cookie 在 PHP 中的区别?下面我们就来总结一下: Cookie 仅由客户端生成.管理并使用,PHP 只是发出指令要求客户端如何生成 Cookie.何时过期等,但是客户端不一定会按照 PHP 的指令办事. Cookie 不是很安全,不法分子可以通过分析本地的 Cookie 进行 Cookie 欺骗.考虑到安全问题,建议将用户的重要信息

  • Java中Cookie和Session的那些事儿

    Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每次访问服务端,请求中都会带上Cookie:Session是服务端技术,在服务端存储用户的访问信息. 使用Cookie传递信息,随着Cookie个数增多和访问量增大,它占用的带宽会越来越大:使用Session保存信息,最大的弱点就是不容易在多台服务器之间共享. 1 Cookie 通俗地讲,当用户使用H

  • SpringBoot中使用Cookie实现记住登录的示例代码

    最近在做项目,甲方提出每次登录都要输入密码,会很麻烦,要求实现一个记住登录状态的功能,于是便使用 Cookie 实现该功能 一.Cookie 简介 Cookie,一种储存在用户本地终端上的数据,有时也用其复数形式 Cookies.类型为"小型文本文件",是某些网站为了辨别用户身份,进行 Session 跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息. 其实 Cookie 就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器.然后客户端

  • java web中 HttpClient模拟浏览器登录后发起请求

    HttpClient模拟浏览器登录后发起请求 浏览器实现这个效果需要如下几个步骤: 1请求一个需要登录的页面或资源 2服务器判断当前的会话是否包含已登录信息.如果没有登录重定向到登录页面 3手工在登录页面录入正确的账户信息并提交 4服务器判断登录信息是否正确,如果正确则将登录成功信息保存到session中 5登录成功后服务器端给浏览器返回会话的SessionID信息保存到客户端的Cookie中 6浏览器自动跳转到之前的请求地址并携带之前的Cookie(包含登录成功的SessionID) 7服务器

  • 详解SpringBoot中Session超时原理说明

    一:前言: 最近支付后台登录一段时间后如果没有任何操作,总是需要重新登录才可以继续访问页面,出现这个问题的原因就是session超时,debug代码后发现session的超时时间是1800s.也就是说当1800秒内没有任何操作,session就会出现超时现象.那这个超时时间是如何设置的呢?然后该如何重新设置此超时时间呢?系统又如何判断session超时的呢?接下来就一一进行解答. 二:系统session超时时间如何默认的? 说明:获取session超时时间的方法为"request.getSess

  • 对比分析php中Cookie与Session的异同

    让大家对Cookie和Session有一个更深入的了解,并对自己的开发工作中灵活运用带来启示. 一.cookie机制 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.IETF RFC 2965 HTTP State Management Mechanism 是通用cookie规范.网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies . 具体来说

随机推荐