JSF登录表单 - 登录成功时仅存储会话

时间:2016-03-20 18:02:03

标签: jsf

我已经使用JSF 2.2和PrimeFaces 5.3构建了登录功能屏幕。但是,我有一个问题。假设用户输入了用户名和密码,但其中一个不正确。发生这种情况时,我向用户显示一条错误消息:“用户名和/或密码不正确”。问题是,那时我正在存储会话。我只想在用户成功登录后存储会话。我的登录表单如下所示:

<f:metadata>
        <f:viewParam name="tipo" value="#{loginTipoController.tipo.tipo}" />
    </f:metadata>

    <h:form id="login">

        <p:focus context="login" />

        <p:graphicImage url="img/logog.JPG" width="448" height="119" />

        <p>Digite su usuario y password.</p>

        <p:outputLabel for="usuario" value="Usuario:" />

        <p:inputText id="usuario" value="#{loginController.login.username}" />

        <p:outputLabel for="password" value="Password:" />

        <p:password id="password" value="#{loginController.login.password}" />

        <p:messages autoUpdate="true" for="usuarioPassword" />

        <p:commandButton value="Login" action="#{loginController.login()}" />

        <p:button value="Regresar" outcome="index.jsf" />

    </h:form>

控制器类(loginController),如下所示:

  1. @ManagedBean     @SessionScoped     公共类LoginController {

        private Login login;
    
        private LoginTipo loginTipo;
    
        private LoginService service;
    
        public Login getLogin() {
            return login;
        }
    
        public void setLogin(Login login) {
            this.login = login;
        }
    
        public LoginService getService() {
            return service;
        }
    
        public void setService(LoginService service) {
            this.service = service;
        }
    
        @PostConstruct
        public void init()
        {   
            login = new Login();
    
            service = new LoginService();
        }
    
        public String login()
        {   
            FacesContext facesCont = FacesContext.getCurrentInstance();
    
            loginTipo = facesCont.getApplication().evaluateExpressionGet(facesCont, 
                    "#{loginTipoController.tipo}", LoginTipo.class); 
    
            login = service.login(login.getUsername(), login.getPassword(), loginTipo.getTipo()); 
    
            if(login.getMensaje_id() != 0)
            {
                FacesContext.getCurrentInstance().addMessage("usuarioPassword",
                        new FacesMessage(login.getMensaje()));
    
                ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    
                ec.invalidateSession();
    
                return "";
            }
            else
            {
                return login.getMensaje();
            }
        }
    
        //logout method
        public void logout()
        {   
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    
            ec.invalidateSession();
    
            try 
            {
                ec.redirect(ec.getRequestContextPath() + "/index.jsf");
            } 
            catch (IOException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    
  2. 我没有放置LoginService()类代码,因为它只是转到数据库并检查用户是否存在。我只想知道我需要做什么才能在用户成功登录时存储会话。

    请注意,在控制器类的login()方法中,当用户登录失败时,我会显示错误消息。之后,我有以下代码:

    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    
    ec.invalidateSession();
    

    我正在摧毁这次会议。我想避免必须这样做!

1 个答案:

答案 0 :(得分:1)

据我所知,您基本上想要在登录失败时清除登录表单。您可以清除表示表单数据的bean属性。

login = new Login();
loginTipo = null;

bean本身不一定需要是会话范围的。它可以是请求作用域,您可以手动将用户对象放入会话中。我理解Login代表用户。在这种情况下,登录成功后,请执行以下操作:

ec.invalidateSession();
ec.getSessionMap().put("login", login);
return "/userhome?faces-redirect=true";

登录用户将在会话范围内以#{login}的形式提供。

在登录前明确地使会话无效是一种很好的安全措施,可以避免会话固定攻击。在每次登录失败时使其失效确实是不必要的。