我有一个应用程序,我将会话超时设置为1小时。但是我不希望用户关闭他的浏览器并再次打开它,他必须再次登录。为此,我需要一种方法来以每个请求刷新cookie到期时间。
我正在使用Spring Boot和Spring Security。我该如何实现此功能。?
我已经使用Interceptor解决了它。这个想法是拦截HTTP请求并修改JSessionId cookie,并将到期时间设置为您想要的任何价值。一旦重新打开浏览器,这将允许曲奇重复使用。默认情况下,JSessionId cookie的最大年龄等于-1,这意味着它在浏览器关闭后立即到期。
public class CookieExpiryRefresher extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, //
Object handler, ModelAndView modelAndView) throws Exception {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies){
if (cookie.getName().contentEquals("JSESSIONID")){
if (cookie.getValue().contentEquals(request.getSession().getId())){
cookie.setMaxAge(60*60*5);
cookie.setPath("/");
response.addCookie(cookie);
break;
}
}
}
}
}
可以注册此拦截器如下:
@Component
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new CookieExpiryRefresher());
}
}
baeldung具有使用过滤器的解决方案。@ https://www.baeldung.com/spring-security-session
public class SessionFilter implements Filter {
@Override
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
Cookie[] allCookies = req.getCookies();
if (allCookies != null) {
Cookie session =
Arrays.stream(allCookies).filter(x -> x.getName().equals("JSESSIONID"))
.findFirst().orElse(null);
if (session != null) {
session.setHttpOnly(true);
session.setSecure(true);
res.addCookie(session);
}
}
chain.doFilter(req, res);
}
}
您只能在interceptor的prehandle中创建,更新和删除cookie。
如果要在调用控制器后添加cookie,则必须使用ControllerAdvice
@ControllerAdvice
public class CookieAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType,
Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
Cookie cookie = new Cookie("cookieName", cookieValue);
ServletServerHttpResponse resp = (ServletServerHttpResponse)response;
resp.getServletResponse().addCookie(cookie);
return body;
}
}