整合Shiro Session和JWT登录

关于JWT原理和相关问题,一定要先阅读我的另一篇文章《JWT技术——基于token的鉴权机制

根据文中的论述,JWT存在许多安全隐患,建议使用HTTPS。

但是本文以实现JWT方案为主,不考虑安全性——JWT方案是可以扩展的,为了提高安全性,可以在后期的设计中去加强。

 

JWT登录的原理:

-> 客户端 携带认证名和密码  发起登录请求 

-> 服务器端验证成功,返回 token 给客户端

-> 客户端保存 token(通常是保存在Cookie或者LocalStorage中)

-> 客户端以后每次请求,都在Header中 携带该Token

-> 服务器端,每次接收非登录请求,都验证Header中是否有token

注意:

  1. 服务端要支持CORS(跨来源资源共享)策略,以便接收其他不同客户端的请求。

  2. 平滑的处理token过期,如果用户一直在活动,需要刷新token,客户端要配合。

 

Session登录的原理:

-> 客户端 携带认证名和密码  发起登录请求 

-> 服务器端验证成功,将用户信息存储下来,生成一个 sessionId, 返回给客户端,并通知客户端将sessionId set到cookie中

-> 客户端自动执行服务器端将sessionId set到cookie中的命令,sessionId被自动保存在cookie中

-> 客户端以后每次请求,都会自动将cookie中的sessionId发送给服务器端

-> 服务器端,每次接收请求,都从cookie中取出sessionId,根据这个id找到存储的用户信息,如果有,说明登录,否则说明未登录或者已过期。

 

两者是非常相似的,不同之处在于:

1、Session登录方式,sessionId是自动保存到cookie中的,且发送请求时,浏览器是自动附加上cookie信息的,这一切的前提是:前后端处于同一域下面,如果不是相同的域,cookie信息是不会自动提交给后端的。

2、Session登录方式,服务器端缓存了登录用户的信息,而JWT方式,服务器端可以不存储任何信息,只要验证Token通过即可,不一定要知道用户信息,实际上JWT方式,JWT的Token本身存储了一些关键数据(比如用户名,过期时间),token是根据密码学算法生成的,无法更改token里面的内容。

3、Session登录方式,缓存的过期时间是由服务器端设定的,而JWT方式,token信息中自带过期时间(服务器端生成token的时候就设定好了过期时间),过期之后token验证失败。

4、Session登录方式,优点是不存在CORS跨域问题,且服务器端处理登录过期很简单、自然。但不支持跨域访问在某些情况下是硬伤!!(比如APP登录)

5、Session登录方式,sessionId是自动保存和发送的,而JWT方案,客户端需要写代码实现token的保存,并配置AJAX的header实现token的发送。

 

Session和JWT登录 整合方案:

1、用类似于JWT的token作为SessionId,客户端采用JWT模式来保存和发送这个sessionId,保存在cookie或localStorage中,发送时用header;

2、为了接收非同源客户端的AJAX请求,服务器端需要启用 CORS(Cross-Origin Resource Sharing) 跨域访问,为指定域名的客户端开通白名单;

3、服务器端采用session的处理方式,保存session信息,并根据请求来更新过期时间,同时,服务器端兼容从cookie或者header中取得sessionId。

 

具体在 Shiro 框架中,实现起来也简单,重写DefaultWebSessionManager的getSessionId方法,加入从header中获取的策略即可,

代码如下:

public class HeaderBasedWebSessionManager extends DefaultWebSessionManager implements WebSessionManager {

 

    @Override

    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {

        Serializable id = super.getSessionId(request, response);

        if (id != null) {

            return id;

        }

        id = getSessionIdFromHeader((HttpServletRequest) request);

        if (id != null) {

            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);

            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);

        }

        return id;

    }

 

    private Serializable getSessionIdFromHeader(HttpServletRequest request) {

        return request.getHeader(getSessionIdName()); // JSESSIONID

    }

 

}

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
项目描述 在上家公司自己集成的一套系统,用了两个多月的时间完成的:Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级开发系统 Springboot作为容器,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为模板引擎,shiro作为安全框架,主流技术 几乎零XML,极简配置 两套UI实现(bootstrap+layer ui),可以自由切换 报表后端采用技术: SpringBoot整合SSM(Spring+Mybatis-plus+ SpringMvc),spring security 全注解式的权限管理和JWT方式禁用Session,采用redis存储token及权限信息 报表前端采用B ootstrap框架,结合Jquery Ajax,整合前端Layer.js(提供弹窗)+Bootstrap-table(数据列表展示)+ Bootstrap-Export(各种报表导出SQL,Excel,pdf等)框架,整合Echars,各类图表的展示(折线图,饼图,直方图等),使用了layui的弹出层、菜单、文件上传、富文本编辑、日历、选项卡、数据表格等 Oracle关系型数据库以及非关系型数据库(Redis),Oracle 性能调优(PL/SQL语言,SQL查询优化,存储过程等),用Redis做中间缓存,缓存数据 实现异步处理,定时任务,整合Quartz Job以及Spring Task 邮件管理功能, 整合spring-boot-starter-mail发送邮件等, 数据源:druid 用户管理,菜单管理,角色管理,代码生成 运行环境 jdk8+oracle+redis+IntelliJ IDEA+maven 项目技术(必填) Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis 数据库文件 压缩包内 jar包文件 maven搭建 Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统 http://localhost:/8080/login admin admin Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值