JSF Login per Ajax validieren. Was ist der Beste Weg?

Phenix

Bekanntes Mitglied
Hallo Zusammen,

die Frage, die ich habe bezieht sich ein wenig auf die Frage im Thema unter meinem, doch irgendwie auch nicht 100%ig.

Ich habe ein Form in dem der Benutzer seinen Nutzernamen und das Passwort angeben soll. Wenn auf den Button geklickt wird, soll überprüft werden ob der User existiert usw. Wenn der Login daneben läuft, soll eine Fehlermeldung angezeigt werden. Per Ajax!

Ich habe das folgendermaßen versucht:

Java:
<h:panelGroup layout="block" styleClass="iets">
                    <h:panelGrid columns="2" >
                        <h:form prependId="false" >
                            <h2>Benutzerbereich</h2>
                            <h:outputLabel value="Benutzername* " for="Benutzername" />
                            <p:keyboard required="true" id="Benutzername" showMode="button">
                                <p:ajax event="blur" update="growl" />
                            </p:keyboard>
                            <h:outputLabel value="Passwort* " for="Passwort" />
                            <p:keyboard password="true" id="Passwort" required="true" showMode="button">
                                <p:ajax event="blur" update="growl" />
                            </p:keyboard>
                            <p:commandButton ajax="true" value="Login" update="growl" actionListener="#{userController.checkUser}" >
                                <f:attribute name="username" value="Phenix" />
                                <f:attribute name="password" value="12345" />
                            </p:commandButton>
                        </h:form>
                    </h:panelGrid>
                </h:panelGroup>

Methode chechUser:

Java:
public void checkUser(ActionEvent event)
    {
        try
        {
            String username = (String) event.getComponent().getAttributes().get("username");
            String password = (String) event.getComponent().getAttributes().get("password");

            if (reader.checkUser(username, "USERNAME", password, "PASSWORD", "USERS"))
            {
                FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Erfolg", "Alles richtig eingegeben");
                throw new ValidatorException(msg);
            } else
            {
                FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Logindaten falsch", "Der eingegebene Benutzername oder das eingegebene Passwort war falsch.");
                throw new ValidatorException(msg);
            }
        } catch (CommunicatorException ex)
        {
            System.out.println(ex.getMessage());
        }
    }

Das Problem ist, dass die Nachrichten in der View nicht angezeigt werden. Auch die Verwendung von h:message hat nicht zum Erfolg geführt. Auf der Seite befindet sich ein p:growl (falls es euch bekannt ist). Am liebsten sollte dieses die Fehlermeldung anzeigen.

Außerdem: Wie kann ich die Werte an den ActionListener übergeben. Bisher passiert das ja statisch via
Code:
<f:attribute name="username" value="Phenix" />

Sorry, für diese Anfängerfrage, doch ich habe im Netz immer nur so umständliche Lösungen für so etwas gefunden.

Edit: Ich sollte vielleicht als Ergänzung anfügen, dass ich nicht direkt mit den Beans kommuniziere, sondern die Kommunikation immer über einen Controller läuft.
 
Zuletzt bearbeitet:
Ok, ich habe es nun so gelöst. Ist es eine gute Idee, diese Logik in einem ActionListener abzuarbeiten oder sollte ich das besser anders lösen. was denkt ihr?

Java:
 <h:form prependId="false" >
                            <h2>Benutzerbereich</h2>
                            <h:outputLabel value="Benutzername* " for="Benutzername" />
                            <p:keyboard required="true" id="Benutzername" value="#{userBean.username}" showMode="button">
                                <p:ajax event="blur" update="growl" />
                            </p:keyboard>
                            <h:outputLabel value="Passwort* " for="Passwort" />
                            <p:keyboard password="true" id="Passwort" value="#{userBean.password}" required="true" showMode="button">
                                <p:ajax event="blur" update="growl" />
                            </p:keyboard>
                            <p:commandButton ajax="true" value="Login" update="growl" actionListener="#{userController.checkUser}" />
                        </h:form>


Java:
 public void checkUser(ActionEvent event)
    {
        try
        {
            FacesContext ctx = FacesContext.getCurrentInstance();
            UserBean user = (UserBean) ctx.getExternalContext().getSessionMap().get("userBean");

            if (reader.checkUser(user.getUsername(), "USERNAME", user.getPassword(), "PASSWORD", "USERS"))
            {
                FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Korrekt", "Korrekt eingeloggt");
                ctx.addMessage(null, msg);
                ctx.renderResponse();
            } else
            {
                FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Logindaten falsch", "Der eingegebene Benutzername oder das eingegebene Passwort war falsch.");
                ctx.addMessage(null, msg);
                ctx.renderResponse();
            }
        } catch (CommunicatorException ex)
        {
            System.out.println(ex.getMessage());
        }
    }

Noch eine Frage: Kann mir einer erklären, wie ich aus einem ActionListener heraus auf eine andere Seite navigiere? Ich habe gelesen, es soll auch ohne eine Navigationsregel möglich sein. Wie geht das?

Danke im Voraus
 
Mir kommt das nicht besonders gut vor. Du benutzt jede Menge direkte relativ "schmutzige" Funktionsaufrufe, auch um an die Werte zu kommen. Wie sauberes Softwaredesign sieht das eigentlich nicht aus. Und eigentlich macht man das mit JSF auch anders.

Ich kenn primefaces zwar kaum (arbeite selber mit richfaces), aber das Grundprinzip dürfte ja immer gleich sein. Generell unterscheidet sich die Variante, das mit ajax zu machen, eh nicht besonders von einem ganz normalen Form-Submit. Und wie man das im Standardfall implementieren würde, ist ja eigentlich klar, oder? Also dafür ist kein extra Beispeil nötig.

Warum kommunizierst Du denn nicht direkt mit den Beans? ich würde eine ActionBean "userController" nehmen, diese hat eine userBean als property und eine login-Funktion, damit geht das doch eigentlich straightforward.
 
Zuletzt bearbeitet:
Hallo,

natürlich hast du recht. Ich habe das Ganze nun etwas überarbeitet. Der Controller hat nun eine Membervariable vom Typ UserBean und kann nun direkt darauf zugreifen.
Wenn sich der Benutzer nun erfolgreich einloggt, soll auf der gleichen Seite ein weiteres Menü gerendert werden, was halt nur eingeloggte Personen sehen können. Ich habe versucht es so zu realisieren, doch es wird nicht angezeigt:

Java:
    private UserBean user;

    public UserController()
    {
        user = new UserBean();
    }

    public void checkUser(ActionEvent event)
    {
        try
        {
            FacesContext ctx = FacesContext.getCurrentInstance();

            if (reader.checkUser(user.getUsername(), "USERNAME", user.getPassword(), "PASSWORD", "USERS"))
            {
                user.setCorrect(true);
                ctx.renderResponse();
            } else

Und in der View:

[XML]
<p:commandButton ajax="true" value="Login" update="growl,loggedIn" actionListener="#{userController.checkUser}" />
</h:form>
</h😛anelGrid>
</h😛anelGroup>
<h😛anelGroup layout="block" id="loggedIn" rendered="#{userController.user.correct}">
<h😱utputText value="du bist eingeloggt!!!!!" />
</h😛anelGroup>
[/XML]

Ne Idee?
 
In welchem Scope ist Deine Bean? Hast Du mal die Getter geprüft (z.B. über den Debugger)?

Ansonsten gestalte ich Loginseiten immer einzeln. Dann prüft ein PhaseListener, ob der Benutzer eingeloggt ist und redirected ggf. wieder auf die Loginseite.
 

Neue Themen


Zurück
Oben