• shiro使用(简单记住我下次自动登录流程)附cookie内容为deleteme的最终解决方法


    既然要做,就做的细致一点,对得起自己!

    写在前面:学过JSP的都知道,这种实现的方式就是cookie,就够了。

    配置shiro.xml,配置cookie.

    1.配置cookie的名字,存活时间以及其他

    
      
      
      
      
      
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.将cookie注入到cookieRememberManager中

    
      
      
      
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.将cookieManager添加到securityManager中

    
            
            
            
            
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基本配置完成,在代码中,当我们根据用户是否勾选了记住我/下次自动登录选项,在subject.login(token)之前,加上一行代码,

    token.setRememberMe(true/false),这样整个流程就基本走完。

    一个巨大的问题:

    测试cookie是否生效,结果,是不生效的,关闭浏览器,重新打开,还是需要登录。后台没有任何报错信息。

    解决思路:

    1.先看看后台是否返回cookie给浏览器了,在谷歌中找到cookie,如下图:

    可以看到,其中cookie确实是有我设置的cookie的名字,说明shiro.xml配置文件中没有错。注意下,这里的cookie的创建时间和失效时间是一样的,并且cookie的内容也不对,是deleteme.

    2.去网上找帖子,找博文,只有一个博主和我有一样的问题,但是没有人提供回复。

    3.没办法,只能去看源码。(以下为自己的解决思路)

    第一步:既然这个cookie内容为deleteme,肯定是哪里有错误,cookie的设置了一下,于是在simpleCookie中找,果然找到了

    第二步:可以看到removeForm中进行了设置,在哪里调用的这个方法呢?simpleCookie中没有,shiro.xml是将simpleCookie交给了cookieRememberManager管理,于是进去找,结果,还真找到了。

    forgetIdentity这个方法调用了removeForm这个方法,我的应该是第一个,因为我在认证过程中传的是Subject.这个方法又是在哪调用的呢?
    
    • 1

    第三步:CookieRememberMeManager中没有调用这个方法的,就去他继承的抽象类AbstractRememberManager中找,在这个抽象类中有一个onFailedLogin的方法,调用了它,于是debug,打断点,但是断点并没有进入onFailedLogin这个方法.瞬间懵逼,这咋整。

    第四步:看了一大堆方法,也不知道干嘛的,看到了onSuccessfulLogin这个方法,打断点,看看进入了没,还真进去了。

    这几步是顺序执行的,跟着断点走,一直到converPrincipalsToBytes这个方法的this.serialize这个位置,断点跟进去,发现有异常被捕获了,上面的try代码块涉及到了流的相关操作

    看到这个提示和断点中的User实体类,我直接明白了,我的User实体类没有实现serializable接口,赶紧实现下接口。因为我自定义realm中关于认证的部分传的是User对象。这里如果你传的是String类型的username,则不会出问题,因为String实现了serializable接口。因为cookie是要返回给浏览器,保存在用户的硬盘里的,那么服务器给浏览器传的东西肯定是一个IO文件,既然涉及到IO,肯定涉及到流的操作,既然对象要实现流的input和output,那么肯定要实现serializable接口.看了源码之后才搞清楚,真是汗颜。

    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(authUser, password, getName());
    
    • 1

    第五步:重新测试,关闭浏览器,重新打开,可以不用验证直接登录。困扰的大问题终于解决。

    经过这个坑,对shiro真是更加清楚了。

    以下为这次跳坑之后,整理的shiro关于rememberMe的流程。

    流程:

    1.shiro会先删除从浏览器获得cookie,并且初始化一个cookie,内容为deleteme.

    2.relam认证成功之后,shiro视当前用户登录成功之后,调用onSuccessfulLogin方法,在DefaultSerializer类中将获得的principal对象通过对象流ObjectOutputStream写入到字节数组中。

    3.第二步没有异常抛出的话则调用CookieRememberMeManager中的rememeberSerializedIdentity方法。如果第二步有异常,则会返回初始化的deleteMe的cookie,并且原来的cookie已经消失,因为第一步直接给删除了。

    4.rememeberSerializedIdentity方法中调用cookie.saeTo方法,直接设置对应的cookie返回给浏览器,如下图:

    至此,一个小功能rememberMe完成。

    本专栏并没有提供相关完整的代码,不过,有一个前后端项目中整合了Shiro,如有需要,代码在这里

  • 相关阅读:
    前端面试题(Vue与网络相关)
    【Redis】SSM整合Redis&注解式缓存的使用
    C语言-数据类型
    Dubbo原理解析,彻底搞懂dubbo (下)
    深入理解Java基本数据类型与引用数据类型
    春游江淮 乐享五一|跟着《承欢记》来绩溪,治愈系的慢生活
    诚信型性格分析,诚信型人格的职业发展
    5大负载均衡算法 (原理图解)
    【广州华锐互动】动物内脏3D模型素材库提供更加丰富的学习资源,提高教学效果
    OpenCV-Java 开发简介
  • 原文地址:https://blog.csdn.net/m0_67394360/article/details/126496246