4

I'm trying to implement a logout in my application, so I made this:

public String logout(){
    try{
        FacesContext facesContext = FacesContext.getCurrentInstance();  
        ExternalContext ex = facesContext .getExternalContext();  
        ex.invalidateSession(); 
        return "success"; 
    }catch(Exception e){
        return "error";
    }
}

But when I check if the user is logged, it says yes:

public class AuthenticateListener implements PhaseListener {


    @Override
    public void afterPhase(PhaseEvent event) {
        AuthorizedUser authorized = (AuthorizedUser) Util.getHandler("authorized");
        if (authorized.getUser() == null) {
            System.out.println("Not Logged");
        } else {
            System.out.println("Logged");
        }
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

}

Am I missing something? Shouldn't I get a new instance of AuthorizedUser (sessionScoped) after invalidating my session?

EDIT: Adding the getHandler, if someone needs it ;)

public static Object getHandler(String handlerName) {

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    ELResolver resolver = facesContext.getApplication().getELResolver();

    Object uh = resolver.getValue(elContext, null, handlerName);
    return uh;
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Montolide
  • 773
  • 3
  • 12
  • 27
  • When is `logout()` being called? Is it the action of something like a `` or ``? If, after logging out, you then perform another request from the browser, does it still look like the user is logged in? I suspect that it's actually working, but that you're observing the state at the wrong time. Also, see http://stackoverflow.com/a/5620582/244191. – Brian Apr 30 '12 at 13:55
  • Got the problem. Had a call on my xhtml to the login method that was commented, but was still being called after accessing the page. This way, the user was always logged in – Montolide May 03 '12 at 17:01

2 Answers2

1

The session is still available in the current request-response. It's not available anymore in the next request. You need to send a redirect after the invalidate so that the browser will be instructed to send a new request on the given URL.

return "success?faces-redirect=true"; 

Or if you're still using old fashioned navigation cases (the return values namely suggests that; it's strange to have a view with filename "success"), then add <redirect/> to the navigation case instead.

If that still doesn't work, then the bug is in how you're storing the user in session. For example, it's instead actually been stored in the application scope which may happen when you mix CDI @Named with JSF @SessionScoped, or when you assigned the logged-in user as a static variable instead of an instance variable.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
-2

Use this piece of code inside logout method:

HttpSession oldsession = (HttpSession) FacesContext
                .getCurrentInstance().getExternalContext().getSession(false);
oldsession.invalidate();

This will work. Let me know please if it was helpful for you.

MikroDel
  • 6,705
  • 7
  • 39
  • 74
  • The `ex.invalidateSession();` does exactly the same and doesn't cause a potential `NullPointerException` as your attempt would do. – BalusC Dec 20 '12 at 13:59