21.Shiro在springboot与vue前后端分离项目里的session管理

1.前言 【21.Shiro在springboot与vue前后端分离项目里的session管理】当决定前端与后端代码分开部署时,发现shiro自带的session不起作用了。
然后通过对请求head的分析,然后在网上查找一部分解决方案。
最终就是,登录成功之后,前端接收到后端传回来的sessionId,存入cookie当中。
之后,前端向后端发送请求时,请求Head中都会带上这个sessionid。
后端代码通过对这个sessionid的解析,拿到正确的session。
2.代码改造 (1)后端代码改造

  1. 添加CustomSessionManager.java
    /** * 类的详细说明 * * @author 郭广明 * @version 1.0 * @Date 2018/11/3014:56 */ public class CustomSessionManager extends DefaultWebSessionManager {/** * 获取请求头中key为“Authorization”的value =https://www.it610.com/article/= sessionId */ private static final String AUTHORIZATION ="Authorization"; private static final String REFERENCED_SESSION_ID_SOURCE = "cookie"; /** *@Description shiro框架 自定义session获取方式
    *可自定义session获取规则。这里采用ajax请求头 {@link AUTHORIZATION}携带sessionId的方式 */ @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { // TODO Auto-generated method stub String sessionId = WebUtils.toHttp(request).getHeader(AUTHORIZATION); if (StringUtils.isNotEmpty(sessionId)) { request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return sessionId; } return super.getSessionId(request, response); }}

  2. 改造ShiroConfig.java
    @Configuration public class ShiroConfig {@Autowired private UserService userService; @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必须设置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 拦截器. Map filterChainDefinitionMap = new LinkedHashMap(); // 配置不会被拦截的链接 顺序判断 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/doLogin", "anon"); filterChainDefinitionMap.put("/swagger-resources", "anon"); filterChainDefinitionMap.put("/v2/api-docs", "anon"); filterChainDefinitionMap.put("/webjars/**", "anon"); filterChainDefinitionMap.put("/swagger-ui.html", "anon"); // :这是一个坑呢,一不小心代码就不好使了; // filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); System.out.println("Shiro拦截器工厂类注入成功"); return shiroFilterFactoryBean; }/** * 注入MyRealm * @return */ @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 设置realm. securityManager.setSessionManager(sessionManager()); securityManager.setRealm(myShiroRealm()); return securityManager; }/** * 配置注解 * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }@Bean public MyRealm myShiroRealm() { return new MyRealm(userService); }@Bean("sessionManager") public SessionManager sessionManager(){ CustomSessionManager manager = new CustomSessionManager(); /*使用了shiro自带缓存, 如果设置 redis为缓存需要重写CacheManager(其中需要重写Cache) manager.setCacheManager(this.RedisCacheManager()); */manager.setSessionDAO(new EnterpriseCacheSessionDAO()); return manager; }}

(2)前端代码改造
  1. 添加CookieUtil.js
    export default { setCookie: (name,value,days) =>{ var d = new Date; d.setTime(d.getTime() + 24*60*60*1000*days); window.document.cookie = name + "=" + value + "; path=/; expires=" + d.toGMTString(); }, getCookie: name =>{ var v = window.document.cookie.match('(^|; ) ?' + name + '=([^; ]*)(; |$)'); return v ? v[2] : null; }, delCookie: name =>{ this.setCookie(name, '', -1); //将时间设置为过去时,立即删除cookie }}

  2. 改造HttpUtil.js
    import axios from 'axios' import doCookie from '@/util/cookieUtil'axios.defaults.headers.common['Authorization'] = doCookie.getCookie("SESSIONID") axios.defaults.baseURL = 'http://127.0.0.1:8080'/** * Get请求 */ export function get(url, callback){ axios.get(url) .then(function (response) { if(response.data.length==0 || response.data=https://www.it610.com/article/=null) { callback(null,true) } else { callback(response.data,true) } }) .catch(function (error) { callback(null,false) }) }export function remove(url, callback){ axios.delete(url) .then(function (response) { if(response.data.length==0 || response.data==null) { callback(null,true) } else { callback(response.data,true) } }) .catch(function (error) { callback(null,false) }) }export function post(url, data, callback){ axios.post(url,data) .then(function (response) { if(response.data.length==0 || response.data==null) { callback(null,true) } else { callback(response.data,true) } }) .catch(function (error) { callback(null,false) }) }export function put(url, data, callback){ axios.put(url,data) .then(function (response) { if(response.data.length==0 || response.data==null) { callback(null,true) } else { callback(response.data,true) } }) .catch(function (error) { callback(null,false) }) }export default { get, post, put, remove, }

转载于:https://www.cnblogs.com/TimerHotel/p/springboot21.html

    推荐阅读