Frontend Logout

Alles rund um Module und Plugins in CONTENIDO 4.10.
mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Frontend Logout

Beitrag von mikedreissig » Mo 9. Jan 2023, 21:06

Liebe Gemeinde,
funktioniert bei euch eigentlich der Frontend-Logout wie er soll? Ich habe einen Logoutbutton nach diesem Schema erstellt ($site_url->build( ['idcat' => '7', 'idart' => '47', 'lang' => $lang, 'logout' => 'true'], true )) und lande auch auf der entsprechenden von mir erstellten Logoutseite, aber wenn ich auf den Browser-Zurückbutton klicke, erhalte ich die Meldung "Formular erneut einreichen?". Wenn ich dies bestätige, lande ich wieder im geschützen Frontendbereich, war also offensichtlich gar nicht abgemeldet.

Habe schon hier geschaut, aber das ist ja schon ganz schön alt
viewtopic.php?f=109&t=3372&hilit=logout%3Dtrue

CONTENIDO Version 4.10.1
Installierte PHP-Version 7.4.33
Datenbankserver-Version 5.7.38-log

Grüße
Michael

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von Faar » Di 10. Jan 2023, 11:11

Moin.
Ich habe das Gefühl, dass hier noch etwas fehlt, ein Bezug zum Frontend.
Dort steht:
// If http global logout is set e.g. front_content.php?logout=true, log out the current user.
Es muss also mit GET übertragen werden oder $logout=true gesetzt werden.
Folglich wäre zu prüfen, ob nach Deinem Code $logout existiert und falls ja, ob es im Context greift.
Was passiert, wenn im Logoutbutton ein $logout = true; gesetzt wird?
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

malsdgtac
Beiträge: 717
Registriert: Fr 12. Mär 2004, 15:50
Kontaktdaten:

Re: Frontend Logout

Beitrag von malsdgtac » Di 10. Jan 2023, 11:18

Könnte es auch sein, dass du dich durch das "Formular erneut einreichen" wieder anmeldest?

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Di 10. Jan 2023, 17:27

Danke für eure Antworten!
Ich habe mal folgendes aus der contenido/includes/frontend/include.front_content.php direkt in meine Abmeldungsseite eingebaut

Code: Alles auswählen

// If http global logout is set e.g. front_content.php?logout=true, log out the
// current user.
if (isset($logout)) {
    $auth->logout(true);
    $auth->resetAuthInfo(true);
    $auth->auth['uname'] = 'nobody';
}
Gleiches Ergebnis, ich bin nach wie vor angemeldet. Hab es auch mit AMR und ohne probiert, keine Änderung.

Könnt ihr vielleicht mal bei einem eurer Projekte testen (4.10.1), ob das bei euch eventuell auch auftritt?

Danke
Michael

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von Faar » Di 10. Jan 2023, 18:33

Es gibt im Frontend-Bereich einige PHP-Warnungen, die zu fehlerhaftem Verhalten führen.
Es hat wohl mit PHP 8 zu tun und ich denke, darum funktioniert das alles nicht mehr.
Ich bekomme gar keine Frontend-Berechtigungen angezeigt, kann also keinen Test machen, weil ich das gar nicht einrichten kann.
Vermutlich aus ähnlichem PHP-Grund meldet Dein Script den User nicht ab.
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Di 10. Jan 2023, 18:45

Der Fehler tritt bei mir bei PHP 7.4.33 auf.

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von Faar » Di 10. Jan 2023, 19:44

Ich finde momentan keinen Anfang der Fehler, es hagelte massenhaft Warnungen vor undefinierten Variablen und Array Keys.
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Di 10. Jan 2023, 20:41

Habe es auch noch mit einer Contenido 4.9.12 getestet, gleiches Ergebnis.

Nur zur Sicherheit, mein Login-Formular sieht so aus

Code: Alles auswählen

// login form mit idcat und idart der passwortgeschützten Landingpage
<form method="post" action="' . $site_url->build( ['idcat' => '134', 'idart' => '1146', 'lang' => $lang], true ).'" name="loginform" id="loginform" target=\"_self\">
// input username
// input password
// submitbutton
</form>
und dort habe ich einen Logoutlink in dieser Form

Code: Alles auswählen

// logout mit idcat und idart der Logoutseite, reine Texseite, kein Formular
<a href="' . $site_url->build( ['idcat' => '7', 'idart' => '1147', 'lang' => $lang, 'logout' => 'true'], true ) . '" target="_self">Logout</a>

xmurrix
Beiträge: 3143
Registriert: Do 21. Okt 2004, 11:08
Wohnort: Augsburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von xmurrix » Mi 11. Jan 2023, 11:40

Hallo Michael,
mikedreissig hat geschrieben:
Mo 9. Jan 2023, 21:06
...Ich habe einen Logoutbutton nach diesem Schema erstellt ($site_url->build( ['idcat' => '7', 'idart' => '47', 'lang' => $lang, 'logout' => 'true'], true )) und lande auch auf der entsprechenden von mir erstellten Logoutseite, aber wenn ich auf den Browser-Zurückbutton klicke, erhalte ich die Meldung "Formular erneut einreichen?". Wenn ich dies bestätige, lande ich wieder im geschützen Frontendbereich, war also offensichtlich gar nicht abgemeldet...
normalerweise ist das Login per Formular (POST) und das Logout ein normaler Link (GET). Du schreibst, dass du einen Logoutbutton erstellt hast, vermutlich handelt es sich auch um ein Link-Button, das am Ende auch per GET-Anfrage die Abmeldung ausführt.

Da das Anmelden per Formular geschieht und das Abmelden per Link, kann man davon ausgehen, dass beim Klick auf den Browser-Zurückbutton wieder das Formular zur Anmeldung abgeschickt wird, denn die Abmeldung geschieht ja nicht per Formular.

Das ist das Standardverhalten des Browsers, aber man kann hier überlegen, wie man das erneute Senden des Formulars umgehen kann. In der Regel löst man das mit dem Post/Redirect/Get-Verfahren, bei der verhindert wird, dass Formulare mehrfach versendet werden können. Ob man das in CONTENIDO einfach einbauen kann, weiß ich jetzt auf Anhieb nicht.

Gruß

xmurrix
CONTENIDO Downloads: CONTENIDO 4.10.1
CONTENIDO Links: Dokumentationsportal, FAQ, API-Dokumentation
CONTENIDO @ Github: CONTENIDO 4.10 - Mit einem Entwicklungszweig (develop-branch), das viele Verbesserungen/Optimierungen erhalten hat und auf Stabilität und Kompatibilität mit PHP 8.0 bis 8.2 getrimmt wurde.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Mi 11. Jan 2023, 19:22

Hallo Murat,
danke für die Erläuterung!

Ich habe nun dieses

Code: Alles auswählen

// login form mit idcat und idart der passwortgeschützten Landingpage
<form method="post" action="' . $site_url->build( ['idcat' => '134', 'idart' => '1146', 'lang' => $lang], true ).'" name="loginform" id="loginform" target=\"_self\">
// input username
// input password
// submitbutton
</form>
so geändert (der Logoutlink führt auf das Anmeldeformular zurück)

Code: Alles auswählen

if (isset($logout)) {
	header("HTTP/1.1 303 See Other");
	header("Location: https://www.test.de");
	exit();
}

// login form mit idcat und idart der passwortgeschützten Landingpage
<form method="post" action="' . $site_url->build( ['idcat' => '134', 'idart' => '1146', 'lang' => $lang], true ).'" name="loginform" id="loginform" target=\"_self\">
// input username
// input password
// submitbutton
</form>
Die Seite www.test.de wird aufgerufen, aber trotzdem erhalte ich über den Browser-Zurückbutton wieder die Meldung "Formular erneut einreichen?"

Wo ist mein Denkfehler?

Grüße
Michael

xmurrix
Beiträge: 3143
Registriert: Do 21. Okt 2004, 11:08
Wohnort: Augsburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von xmurrix » Mi 11. Jan 2023, 21:09

Hallo Michael,

wenn du das im Loginformular machst, musst du sicherstellen, dass in CONTENIDO die Ausgabepufferung für die Seite aktiviert wird, ansonten gibt PHP den HTML-Code der Seite bis zum Loginformular aus, dann kannst du nicht mit der HTTP-Header eine Weiterleitung machen.
In der Regel ist die Ausgabepufferung für alle Frontend-Seiten aktiv, also kannst du das zuvor Geschriebene nur als eine Anmerkung betrachten.

Nun zum Code. Ich würde das wie folgt machen:

Code: Alles auswählen

if (isset($logout)) {
        header("Location: https://www.test.de", true, 303);
        cRegistry::shutdown();
	exit();
}
Wichtig ist hier der Aufruf der Funktion "cRegistry::shutdown();". Die sorgt nämlich dafür, dass Änderungen in der Session persistiwert werden, bevor die Ausführung beendet wird. So könnte das vielleicht funktionieren.

Gruß
Murat
CONTENIDO Downloads: CONTENIDO 4.10.1
CONTENIDO Links: Dokumentationsportal, FAQ, API-Dokumentation
CONTENIDO @ Github: CONTENIDO 4.10 - Mit einem Entwicklungszweig (develop-branch), das viele Verbesserungen/Optimierungen erhalten hat und auf Stabilität und Kompatibilität mit PHP 8.0 bis 8.2 getrimmt wurde.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Di 17. Jan 2023, 17:43

Hallo Murat,

danke für den Hinweis. Ich habe mich nun durch alles durchgewühlt, was ich zu dem Thema finden konnte, und viel ausprobiert:

Code: Alles auswählen

if (isset($logout)) {
	cRegistry::shutdown();
	session_start();
	session_unset();
	session_destroy();
	session_write_close();
	$sess->unregister("auth");
	$sess->freeze();
		
	header("HTTP/1.1 303 See Other");
	header("Location: https://www.test.de");
		
	exit();
}
Nichts davon hilft. Um auszuschließen, dass das Verhalten durch eines meiner Module hervorgerufen wird, habe ich den Demo-Mandanten von Contenido installiert und dort tritt das Problem auch auf ...

IONOS
Contenido 4.10.1 Develop
Installierte PHP-Version 8.1
Datenbankserver-Version 8.0.26

Grüße
Michael

xmurrix
Beiträge: 3143
Registriert: Do 21. Okt 2004, 11:08
Wohnort: Augsburg
Kontaktdaten:

Re: Frontend Logout

Beitrag von xmurrix » Di 17. Jan 2023, 23:11

Hallo Michael,

testhalber habe ich bei einer CONTENIDO Installation, folgende Änderung im "form_login" Modul eines Beispielmandanten gemacht:

Code: Alles auswählen

if ($auth->auth["uid"] == "nobody") {
    // ...
} else {

    if (!empty($_POST['username']) && !empty($_POST['password'])) {
        cRegistry::shutdown();
        $url = cUri::getInstance()->build([
            'idart' => $article->get('idart'),
            'lang' => $article->get('idlang'),
        ], true);
        header("Location: $url", true, 303);
        exit();
    }

    // ...
}
Im Else-Zweig, also die Stelle, die für angemeldete Benutzer ist, wird geprüft, ob es POST-Werte mit 'username' und 'password' gibt. Falls ja, handelt es sich um ein Login, das gerade stattgefunden hat. In diesem Fall wird die Session gesichert und eine Weiterleitung auf die aktuelle Seite gemacht.

1. Gehe ich nach den Anmeldung mit der Browser-Zurück Schaltfläche zur vorherigen Seite, sehe ich, dass ich angemeldet bin und habe die Option, mich abzumelden.

2. Melde ich mich an und melde ich mich danach wieder ab und gehe über die Browser-Zurück Schaltfläche zu vorherigen Seiten, bleibe ich wie erwartet abgemeldet.

In beiden Fällen wird das Login-Formular nicht mehr erneut versendet, wenn man mit per Browser-Zurück vorherige Seiten Aufruft. So wolltest du das doch haben oder?

Das Problem bei dir war, dass du das Post/Redirect/Get bei der Abmeldung gemacht hast und nicht bei der Anmeldung.

Grüße
Murat
CONTENIDO Downloads: CONTENIDO 4.10.1
CONTENIDO Links: Dokumentationsportal, FAQ, API-Dokumentation
CONTENIDO @ Github: CONTENIDO 4.10 - Mit einem Entwicklungszweig (develop-branch), das viele Verbesserungen/Optimierungen erhalten hat und auf Stabilität und Kompatibilität mit PHP 8.0 bis 8.2 getrimmt wurde.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Do 16. Feb 2023, 19:39

upps, hab mich vertippt, unten der richtige Post
Zuletzt geändert von mikedreissig am Do 16. Feb 2023, 19:47, insgesamt 2-mal geändert.

mikedreissig
Beiträge: 83
Registriert: Di 10. Jan 2006, 19:28
Kontaktdaten:

Re: Frontend Logout

Beitrag von mikedreissig » Do 16. Feb 2023, 19:44

Hallo Murat,

späten Dank für das prima Codebeispiel! Warum es bei mir nicht funktioniert hat, hatte folgenden Grund:

Ich habe die Post Action des Anmeldeformulars auf eine Landingpage gesetzt

Code: Alles auswählen

// login form mit idcat und idart der passwortgeschützten Landingpage
<form method="post" action="' . $site_url->build( ['idcat' => '134', 'idart' => '1146', 'lang' => $lang], true ).'" name="loginform" id="loginform" target=\"_self\">
Die Post Action muss aber auf das Loginformular gesetzt werden

Code: Alles auswählen

// login form mit idcat und idart des Loginformulars
<form method="post" action="' . $site_url->build( ['idcat' => $idcat, 'idart' => $idart, 'lang' => $lang], true ).'" name="loginform" id="loginform" target=\"_self\">
und dort wird nach erfolgreicher Anmeldung eine Weiterleitung auf die Landingpage durchgeführt

Code: Alles auswählen

if ( $auth->auth['uid'] == 'nobody') {
// login form
} else {
	if ( ! empty( $_POST['username'] ) && ! empty( $_POST['password'] ) ) {
		// login form has been called by refresh or browser history button
		// redirect to empty login form
		cRegistry::shutdown();
		$url = cUri::getInstance()->build([
			'idart' => $article->get('idart'),
			'lang' => $article->get('idlang'),
		], true);
		header("Location: $url", true, 303);
		exit();
	} else {
		// login successful, redirect to landing page
		header( 'Location: ' . $site_url->build( ['idcat' => $landing_page_idcat, 'idart' => $landing_page_idart, 'lang' => $lang], true ), true, 303 );
		exit();
	}
}
}
Nochmal danke und Grüße
Michael
Zuletzt geändert von mikedreissig am Fr 17. Feb 2023, 16:04, insgesamt 1-mal geändert.

Antworten