shiro 默认是把 session id 存放在 cookie 中的,如果前后台同源会在请求的时候自动带上 cookie,这样子后台就可以从 cookie 中拿到 session id,但是如果跨域就无法获取到 cookie,所以 session id 每次都无法获取到,每次都会重新生成新的 session id。
解决办法:自定义获取 session id 的方法,从请求头中获取,登陆接口返回 session id,前后端约定将 session id 放在请求头的 Authorization 字段中。
OnlineWebSessionManager 自定义 session 管理器:
public class OnlineWebSessionManager extends DefaultWebSessionManager {
private static final Logger log = LoggerFactory.getLogger(OnlineWebSessionManager.class);
/**
* 自定义获取 session Id 类
* @param request
* @param response
* @return
*/
@Override
public Serializable getSessionId(ServletRequest request, ServletResponse response) {
return getReferencedSessionId(request, response);
}
/**
* 获取sessionId从请求中
*
* @param request
* @param response
* @return
*/
private Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {
String id = getSessionIdCookieValue(request, response);
if (id != null) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "cookie");
} else {
id = getUriPathSegmentParamValue(request);
if (id == null) {
// 获取请求头中的session
id = WebUtils.toHttp(request).getHeader("Authorization");
if (id == null) {
String name = getSessionIdName();
id = request.getParameter(name);
if (id == null) {
id = request.getParameter(name.toLowerCase());
}
}
}
if (id != null) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "url");
}
}
if (id != null) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
}
return id;
}
// copy from super class
private String getSessionIdCookieValue(ServletRequest request, ServletResponse response) {
if (!isSessionIdCookieEnabled()) {
log.debug("Session ID cookie is disabled - session id will not be acquired from a request cookie.");
return null;
} else if (!(request instanceof HttpServletRequest)) {
log.debug("Current request is not an HttpServletRequest - cannot get session ID cookie. Returning null.");
return null;
} else {
HttpServletRequest httpRequest = (HttpServletRequest) request;
return getSessionIdCookie().readValue(httpRequest, WebUtils.toHttp(response));
}
}
// copy from super class
private String getUriPathSegmentParamValue(ServletRequest servletRequest) {
if (!(servletRequest instanceof HttpServletRequest)) {
return null;
} else {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String uri = request.getRequestURI();
if (uri == null) {
return null;
} else {
int queryStartIndex = uri.indexOf(63);
if (queryStartIndex >= 0) {
uri = uri.substring(0, queryStartIndex);
}
int index = uri.indexOf(59);
if (index < 0) {
return null;
} else {
String TOKEN = "JSESSIONID" + "=";
uri = uri.substring(index + 1);
index = uri.lastIndexOf(TOKEN);
if (index < 0) {
return null;
} else {
uri = uri.substring(index + TOKEN.length());
index = uri.indexOf(59);
if (index >= 0) {
uri = uri.substring(0, index);
}
return uri;
}
}
}
}
}
// copy from super class
private String getSessionIdName() {
String name = getSessionIdCookie() != null ? getSessionIdCookie().getName() : null;
if (name == null) {
name = "JSESSIONID";
}
return name;
}
}