Grebalb
Grebalb

Reputation: 113

Changing the value of a JSF SessionScoped Bean to log out user

I'm making a small website for a school project, but I'm struggling a bit with how to log a user out. The way I handle logging a user in is simply by writing their username to a @SessionScoped bean, and the using that to access the rest of their information. My plan to log them out is then to simply set the username back to null.

UserBean.java

@Data
@Named
@SessionScoped
public class UserBean implements Serializable {

    private String username;

    public boolean isLoggedIn() {
        return username != null;
    }

}

LoginController.java

@Named
@RequestScoped
public class LoginController {

    @Inject
    private UserBean userBean;

    @EJB
    private AccountDAO accountDAO;

    @Inject
    private LoginBackingBean loginBackingBean;


    public void validateEmailAndPassword() {

        if (accountDAO.usernameExist(userBean.getUsername())) {
            if (!(accountDAO.getAccountByUsername(userBean.getUsername())).getPassword().equals(loginBackingBean.getPassword())) {
                String msg = "Username or Password is incorrect";
                throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "", msg));
            }
        }
    }

    public void login() {
        userBean.setUsername(loginBackingBean.getUsername());
    }

}

LogoutController.java

@Named
@RequestScoped
public class LogoutController {

    @Inject
    private UserBean userBean;

    public void logout() {
        userBean.setUsername(null);
    }

}

xhtml insert that its seeing called from (menuDropdown.xhtml):

<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      >

    <h:body>
        <ui:composition>
            <button class="btn btn-outline-dark" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                menu
            </button>
            <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                <p:link class="dropdown-item" href="#">

                </p:link>
                <div class="dropdown-divider"></div>
                <div class="dropdown-item">
                    <h:commandButton class="btn btn-primary" value="Sign out" action="#{logoutController.logout}"></h:commandButton>
                </div>
            </div>
        </ui:composition>
    </h:body>
</html>

And this is how I call the logoutController:

<h:commandButton class="btn btn-primary" value="Sign out" action="#{logoutController.logout()}"></h:commandButton>

Right now the login method works great, and i can get the username from the bean by writing #{userBean.username}. However, for some reason nothing happens when i press the commandButton to log the user out. Am I calling it in an incorrect way or is there something else that is going on here?

Upvotes: 1

Views: 338

Answers (1)

fuggerjaki61
fuggerjaki61

Reputation: 821

To effectively logout an user the session should be destroyed and with it all possibilties to remain logged in (deleting cookies, etc.). To destroy the session the logout method must contain this:

FacesContext.getCurrentInstance().getExternalContext().invalidateSession();

This invalidates (destroys) the current session and all values will be reset and if the user remains on the side a new session with default and new id values will be created.

Also redirecting to a public view is a good idea so the user does not see a 403 page. Then just return:

return "/index?faces-redirect=true";

Some Lecture:

JSF life after logout

How to create, access and destroy session in JSF managed bean?

Performing user authentication in Java EE / JSF using j_security_check

Upvotes: 1

Related Questions