JSF / primefaces会话-会话丢失

折腾

我是JSF编程的新手,我的登录/会话有问题,登录后会丢失。

我想实现一种简单的登录方式,使用户可以输入用户名和密码。所以我写了一个LoginController:

@ManagedBean
@SessionScoped
public class LoginController extends AbstractController{

     @PostConstruct
    public void initialiseSession() {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
    }

    private String username = "null";
    private String password;
    private boolean loggedIn = false;

    @Inject 
    private EmployeeService employeeService;


    public static final String employeeSessionKey = "user";

    public LoginController() {

    }

    public String login() {
//check username and password and if true redirect to "/"
}

我的login.xhtml看起来像:

<h:form id="loginForm">

            <h:outputLabel style="font-size:24px" value="Bitte melden Sie sich an!"/>

            <p:panelGrid columns="2">

                <p:outputLabel id="userOutput"  for="userInput" value="Benutzername"/>
                <p:inputText id="userInput" value="#{loginController.username}"></p:inputText>
                <p:outputLabel id="passwordOutput" for="passwordInput" value="Passwort"/>
                <p:inputText id="passwordInput" type="password" value="#{loginController.password}"></p:inputText>

                <h:outputText value="Logindaten merken?" id="outputRememberLogin">
                    <p:selectBooleanCheckbox id="loginCheckbox">
                    </p:selectBooleanCheckbox>
                    <p:spacer width="10" id="loginFormLittleSpacer"></p:spacer>
                </h:outputText>

                <p:commandButton id="loginButton" value="Anmelden" action="#{loginController.login()}" ajax="false" >
                </p:commandButton>
            </p:panelGrid>
        </h:form>  

因此,当我登录时重定向有效。但是,当我转到另一个.xhtml页面时,会话会丢失。

为了测试这一点,我把

<p:outputLabel value="#{loginController.username}"/>

在我的页面上。登录后,用户名变为“ null”。

我在这个问题上疯了。

有任何想法吗?

之前感谢。

阿迪迪

您的LoginControllerbean看起来像它的注释还可以,并且代码看起来应该可以工作。但是,您可能还需要检查其他几件事。其中一些可能是显而易见的,但是您的问题缺少一些细节,因此我不确定您可能具有什么经验水平以及从这个答案开始的地方。因此,我从头开始(几乎)...


1.域名配置

要使用会话,必须使用合格的域名。将请求发送到IP地址将不允许会话工作,因为客户端浏览器仅将会话信息发送到完全限定的域名(http://example.com/)。如果您使用IP(例如“ http://127.0.0.1:8080/MyApp ”)调用Web应用,则会话数据将永远不会发送到您的Web应用,并且每个会话都会创建一个新的会话要求。确保对应用程序的每个请求都使用完全限定的域名和路径,例如“ http:// localhost:8080 / MyApp ”。


2.应用程序配置

检查您的Web应用程序的<session-config>配置是否正确设置。默认配置应允许您的代码工作而不必添加任何特定内容,因此,如果您未添加任何内容,请不必为此担心。但是,您可能要确保没有任何事情可以阻止会话被重用。

  • 会话Cookie应启用(<tracking-mode>COOKIE</tracking-mode>
  • 超时时间应足够长,以至于第二个请求(<session-timeout>60</session-timeout>之前不会过期
  • Cookie路径应正确设置以供您使用(<path>/</path>

以下是我使用的常见会话配置…

<session-config>
    <session-timeout>60</session-timeout>  
    <tracking-mode>COOKIE</tracking-mode>
    <cookie-config>
        <path>/</path>                       
        <http-only>true</http-only> 
        <secure>false</secure>
    </cookie-config>
</session-config>

3.客户端上的会话Cookie跟踪

如果以上几点仍不能解决问题,您可以通过监视应用程序与客户端浏览器之间的请求和响应流量来真正开始进入会话跟踪。会话信息通过名为“ JSESSIONID”的cookie(或查询字符串参数,如果禁用cookie)来回传递。其值将是唯一会话的ID,并且对于每个请求都必须相同,以确保您的Web应用程序跟踪相同的会话。以下重点介绍了一些需要寻找的东西……

确保将“ JSESSIONID”会话Cookie正确发送到客户端浏览器,并随每个后续请求一起发送回去。您可以使用Chrome或Safari的网络开发人员工具(在“网络”标签下)或单独的实用程序(例如Wireshark)来执行此操作。

  • 确保第一个请求的响应中存在“ JSESSIONID” cookie……这将使您知道您的Web应用程序至少正在创建会话和响应Cookie。
  • 确保来自客户端浏览器的第二个请求正在传递回“ JSESSIONID” cookie……这是您的Web应用知道使用哪个现有会话的唯一方法。
  • 确保“ JESSIONID” Cookie的路径为“ /”(在浏览器中可能显示为“ N / A”)或您的网络应用程序的路径(例如,“ / MyApp”)……客户端浏览器只会将Cookie发送到与每个域相关联的域和路径。例如,如果您的登录页面为“ http://example.com/MyApp/login ”,则“ JSESSIONID” cookie的路径可能为“ / MyApp”(默认情况下),如果以下请求将不会返回该路径。设为“ http://example.com/ ”(不带“ / MyApp”路径)。默认路径是Web应用程序的名称('/ MyApp'),可以使用<path>上面指示配置项进行更改

4. Bean中的会话管理(附加信息)

在您的initialiseSession()方法中,FacesContext.getCurrentInstance().getExternalContext().getSession(true);不会保存返回的会话对象,并且此行实际上什么也不做。@SessionScoped注释将已经创建了一个会话,并增加了“JSESSIONID” cookie来响应之前initialiseSession()被调用。因此,调用的唯一原因getSession(true)是要将会话保存到Bean中的私有对象,就像这样...

@ManagedBean
@SessionScoped
public class LoginController extends AbstractController{

    // Create a global, private member for storing the session data...
    private HttpSession session;

    @PostConstruct
    public void initialiseSession() {
        // Assign the session to the global member…
        session = FacesContext.getCurrentInstance().getExternalContext().getSession(true); 
    }

同样,getSession(true)在您的示例中不需要调用,因为SessionScopedBean已经创建了会话。仅当您打算更新或使用会话对象(例如,添加属性或修改设置)时,才需要以上代码。


总之

仔细检查上述1 – 3点。我认为在以后的请求中不会将“ JSESSIONID” cookie发送回去。如果您可以确认每个请求中都包含“ JSESSIONID” cookie(具有相同的值),则问题与会话无关,并且可能与login()方法中的代码有关

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章