zoukankan      html  css  js  c++  java
  • shiro遇到的坑-重写sessionManager遇到的坑

    最近公司开发一个微信小程序项目加shiro的项目。因为微信小程序是不使用cookie,使用的是 storage 。那么我们就不能使用传统的方式来保持登录状态了。

    1.首先和网上的一样,先重写一个Session管理器

    public class MySessionManager extends DefaultWebSessionManager {
        private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
    
        @Override
        protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
            System.out.println("执行session管理器>>>>>>>>>>>>>>>>>>>>>>>>");
            String id = WebUtils.toHttp(request).getHeader("TOKEN");
            if(StringUtils.isEmpty(id)){
                //如果没有携带id参数则按照父类的方式在cookie进行获取
                return super.getSessionId(request, response);
            }else{
                //如果请求头中有 token 则其值为sessionId
                request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,REFERENCED_SESSION_ID_SOURCE);
                request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,id);
                request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
                return id;
            }
        }
    }

    2.将自定义的session管理器交给spring管理

    @Configuration
    public class ShiroConfig {
        @Bean
        public DefaultWebSecurityManager securityManager(){
            DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
            manager.setRealm(realm());
            manager.setSessionManager(defaultWebSessionManager());
            return manager;
        }
        @Bean
        public DefaultWebSessionManager defaultWebSessionManager(){
            MySessionManager manager = new MySessionManager();
            return manager;
        }
       ......   
    }

    到这里看样子似乎是没有什么事情了,但是事与愿违,因为我登陆成功之后,每次都被登录过滤器给拦截了。这是为啥嘞?

    经过几轮的debug调试才发现,原来在调用完之后 getSessionId方法之后会有一个设置过期时间的过程(当然这个很正常),默认给设置的是1800,刚开始我觉得没什么毛病啊。就没理他,可是继续往下debug的时候发现报错信息竟然是回话已超时,之后就被登录过滤器给定义为登录失败了(囧)。话说不是已经设置了默认的过期时间了吗? 然后我不服,重写了设置过期时间的方法

     @Override
        public void setTimeout(SessionKey key, long maxIdleTimeInMillis) throws InvalidSessionException {
            super.setTimeout(key, 3600000);
        }

    结果就好了。一定要仔细看第二个参数 maxIdleTimeInMillis 这是最大过期时间的毫秒值啊!!!默认给个1800,不就是1.8秒吗?那这样的话想要让这个回话不过期只能自己设置一个比较大的过期时间了,或者你可以做这时间上最快的男人每1.8秒内就请求一次,这样shiro就会重置过期时间。

  • 相关阅读:
    IO 模型
    进程、线程、锁
    用多线程,实现并发,TCP
    同步锁(互斥锁),GIL锁(解释器层面的锁),死锁与递归锁
    Java项目中的常用的异常2
    JAVA项目中的常用的异常处理情况1
    添加学生信息web界面连接数据库
    jdbc下载路径
    添加学生信息 web界面 并且连接数据库
    正则表达式
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/11848336.html
Copyright © 2011-2022 走看看