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*/@Overridepublic 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) {// 获取请求头中的sessionid = 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 classprivate 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 classprivate 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 classprivate String getSessionIdName() {String name = getSessionIdCookie() != null ? getSessionIdCookie().getName() : null;if (name == null) {name = "JSESSIONID";}return name;}}
