1

これが私のログアウト方法です:

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";
}

このメソッドを呼び出した後、ブラウザ履歴のナビゲーションは引き続き機能しています。どうすればこれを解決できますか?

4

1 に答える 1

6

応答ヘッダーを設定すると、現在の応答のみに適用され、以前のすべての応答 (制限されたページ) または将来の応答 (リダイレクト (!) 以降) には適用されません。実際には、制限された要求のすべての応答でブラウザーのキャッシュをオフにしたいと考えています。実際、コメントで推測したように、これにはサーブレット フィルターを使用する必要があります。

もう 1 つの問題は、 を呼び出すとresponse.setHeader()、基本的に以前に設定されたヘッダーをオーバーライドしていることです。あなたはそれをしたくありません. andが存在しmust-revalidateない場合、 はまったく効果がありません. カンマ区切りの値を単一のヘッダーとして設定するか、 を使用する必要があります。no-cacheno-storeresponse.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).
}

この例では、制限されたすべてのページが/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";
}
于 2012-09-22T09:37:39.287 に答える