Bas*_*suz 1 jsf logout browser-history jsf-2
这是我的注销方法:
public String logout() throws IOException, ServletException
{
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext ec = context.getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
HttpServletResponse response = (HttpServletResponse) ec.getResponse();
final HttpServletRequest request = (HttpServletRequest)ec.getRequest();
session.invalidate();
Cookie[] cookies = request.getCookies();
Cookie opentoken = null;
for(Cookie c : cookies){
if (c.getName().equals("opentoken")){
if (session != null){
opentoken = c;
opentoken.setMaxAge(0);
opentoken.setValue("");
response.addCookie(opentoken);
response.sendRedirect(request.getContextPath());
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "no-store");
response.setHeader("Cache-Control", "must-revalidate");
response.setHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT");//past date
}
break;
}
}
context.getExternalContext().getSessionMap().remove("#{LogoutBean}");
return "login.xhtml?faces-redirect=false";
}
Run Code Online (Sandbox Code Playgroud)
调用此方法后,浏览器历史记录中的导航仍然有效.我怎么解决这个问题?
设置响应标头时,它仅适用于当前响应,而不适用于所有先前的响应(受限页面)或将来的响应(重定向(!)及其后).实际上,您希望在受限请求的所有响应中关闭浏览器缓存.事实上,正如您在评论中所猜测的那样,您应该使用servlet过滤器.
另一个问题是,当你打电话时response.setHeader(),你基本上覆盖任何以前设置的标题.你不想这样做,将must-revalidate有完全若没有效果no-cache和no-store不存在.您需要将值commaseparated设置为单个标头,或者使用response.addHeader().
总而言之,您应该在webapp中拥有这样的类:
@WebFilter("/app/*")
public class NoCacheFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(req, res);
}
// ... (just implement init() and destroy() with empty bodies).
}
Run Code Online (Sandbox Code Playgroud)
此示例假定/app/*URL模式后面的所有受限页面都可用.如果你是不同的,例如/secured/*,/user/*,/admin/*等等,那么你需要改变的URL模式@WebFilter相应.
完成后,您logout()可以简化如下:
public String logout() {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
if (ec.getRequestCookieMap().get("opentoken") != null) {
ec.addResponseCookie("opentoken", null, Collections.<String, Object>singletonMap("maxAge", 0));
}
return "login.xhtml?faces-redirect=true";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3116 次 |
| 最近记录: |