1.前言
当决定前端与后端代码分开部署时,发现shiro自带的session不起作用了。
然后通过对请求head的分析,然后在网上查找一部分解决方案。
最终就是,登录成功之后,前端接收到后端传回来的sessionId,存入cookie当中。
之后,前端向后端发送请求时,请求Head中都会带上这个sessionid。
后端代码通过对这个sessionid的解析,拿到正确的session。
2.代码改造
(1)后端代码改造
添加CustomSessionManager.java
-
/**
-
* 类的详细说明
-
*
-
* @author 郭广明
-
* @version 1.0
-
* @Date 2018/11/3014:56
-
*/
-
public class CustomSessionManager extends DefaultWebSessionManager {
-
-
/**
-
* 获取请求头中key为“Authorization”的value == sessionId
-
*/
-
private static final String AUTHORIZATION ="Authorization";
-
-
private static final String REFERENCED_SESSION_ID_SOURCE = "cookie";
-
-
/**
-
* @Description shiro框架 自定义session获取方式<br/>
-
* 可自定义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);
-
}
-
-
}
-
改造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<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
-
// 配置不会被拦截的链接 顺序判断
-
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");
-
-
// <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
-
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
-
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)前端代码改造
添加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
-
}
-
-
}
-
改造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==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,
-
}
-