6

在 JSF 中,似乎会话是在成功登录之前创建的。即简单地请求登录页面会导致创建一个新会话。

为收到的每个请求而不是每个成功登录的用户创建会话似乎非常浪费(并且容易受到 DDoS 攻击)。

下面的代码非常通用,但显示了我所指的那种简单场景。

索引.xhtml:

<html>
    <body>
        <h:form id="login">
            <h:outputLabel for="username">Username</h:outputLabel>
            <p:inputText id="username" name="username" value="#{userController.username}"/>
            <h:outputLabel for="password">Password</h:outputLabel>
            <p:password id="password" name="password" value="#{userController.password}"/>

            <p:commandButton id="loginButton" value="login" action="#{loginController.login}"/>
        </h:form>
    </body>
</html>

登录控制器.java

@ViewScoped
public class LoginController implements Serializable {

    String username;
    String password;

    public void login(){
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        if (request.getSession(false) == null){
            System.out.println("No session.");
        } else {
            System.out.println("Session already exists.");
        }

        try {
            request.login(username, password);
        } catch (ServletException e) {
            FacesContext.getCurrentInstance.addMessage(null, new FacesMessage("Login failure", e.getMessage()));
        }
    }

    // username and password getters/setters

}

编辑:杂乱无章的代码示例已修复

4

1 回答 1

8

首先,您的测试方法是完全错误的。

if (request.getSession() == null){
    System.out.println("No session.");
} else {
    System.out.println("Session already exists.");
}

请仔细阅读无参数方法的javadoc 。getSession()你会意识到它永远不会回来null

回到具体问题,默认情况下 JSF 确实会自动创建会话,因为 JSF 视图状态必须存储在那里。如果将 JSF 状态保存方法设置为client而不是server,则它不会存储在 session 中,因此不需要创建 session。

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

在即将到来的 JSF 2.2 中,您也可以将 bean 放在请求范围内并使用它<f:view transient="true">来完全无状态。这适用于自 Mojarra 2.1.19 起才可用的当前 JSF 2.1 版本。另请参阅例如来自 Mojarra 开发人员之一的此博客。

于 2013-02-12T14:06:50.417 回答