【问题标题】:Don't use session on certain url不要在某些 url 上使用 session
【发布时间】:2016-09-29 09:35:23
【问题描述】:
我正在尝试制作一个可以加载的特定 api url,但不会更新用户的会话“上次活动”时间。
我已经设置好,如果我的用户在 60 分钟内不活动,则通过 HttpSession.setMaxInactiveInterval()、server.session.timeout 和 spring security 退出,效果很好。现在,我正在尝试构建一个 api 调用,客户端可以调用该调用来检查他们的会话在过期前还有多长时间。但是,问题的症结在于,如果我调用一个 api,它会将其视为用户活动,并将会话再更新 60 分钟,从而达到目的。
我希望也许有一种方法可以禁止对某个 url 使用会话。然后我可以通过发送的cookie手动获取会话ID,手动查找他们的会话对象以从中获取我需要的信息,而无需更新最后一个活动。
【问题讨论】:
标签:
spring
session
tomcat
spring-boot
【解决方案1】:
您最好编写自己的会话失效逻辑。
如果没有大量的 hack 工作,您将无法手动控制 tomcat 访问时间行为。
您可以编写一个 servlet 过滤器来跟踪页面(除了白名单页面)的最后一次访问时间,并使超过阈值的会话无效。
public class AccessTimeFilter implements Filter {
private static final long ACCESS_TIME_WINDOW = 30 * 60 * 1000;//30 Mins
private static final Set<String> IGNORED_URLS = new HashSet<>(Arrays.asList("/myurl", "/someOtherUrl"));
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession();
Long realLastAccessedTime = (Long) session.getAttribute("realLastAccessedTime");
if(realLastAccessedTime != null &&
realLastAccessedTime < (System.currentTimeMillis() - ACCESS_TIME_WINDOW)){
session.invalidate();
}
doFilter(req, res, chain);
String url = request.getServletPath();
if(!IGNORED_URLS.contains(url)){
session.setAttribute("realLastAccessedTime", System.currentTimeMillis());
}
}