jQuery-Login Screenshot

Nun habe ich mich ja in letzter Zeit neben CakePHP auch mit dem jQuery-Framework beschäftigt, und in diesem Zusammenhang eine kleine “Probeanwendung” gebaut, nämlich eine Login-Seite mit Ajax-Funktionalität. Für den ein oder anderen stellt sich nun sicherlich die Frage, ob solch eine Funktion wirklich sinnvoll ist…doch für mich zählt hier eher die Erklärung als der Sinn des Ganzen :-).

Wie das Ganze später aussehen könnte seht ihr in dieser kurzen Demo (richtiger Login: gast:gast). Das ganze wurde grafisch natürlich ein wenig aufgepeppt. Um die jQuery-Animationen auf dem variablen Hintergrund hinzubekommen musste auf das PNG-Format zurückgegriffen werden, zudem wurde für die IE6-User ein PNG-Behaviour eingesetzt.

Nun aber Butter bei die Fische.

Was das XHTML angeht bleibt eigentlich alles beim alten, denn gerade das ist ja das Positive an jQuery: Man braucht den (X)HTML-Quelltext nicht wirklich anzufassen.

Daher hier erstmal das komplette Javascript:

jquery-script.js

$(document).ready(function(){
	$("#login").Bounce(70);
	$("#footbar").slideDown("slow");
	$("input").focus(function(){ 
		$(this).parent().addClass("active");
	});
	$("input").blur(function(){ 
		$(this).parent().removeClass();
	});
	$('#login form').submit(function(e){
		e.preventDefault();
		var username = $("#username input").attr('value');
		var password = $("#password input").attr('value');
		$.ajax({
			type: "POST",
			timeout: 7000,
			data: {username: username, password: password},
			url: "login",
			success: function(result) {
				if(result != "true") {
					$("#ajax_load").animate({opacity: 1.0}, 500).fadeOut(500);
					$("#messages").append('<div id="ajax_error">Anmeldung war nicht erfolgreich!</div>');
					$("#login").Shake(4);
				}
				else {
					$("#ajax_load").fadeOut(200);
					$("#messages").append('<div id="ajax_accept">Erfolgreich, sende an System...</div>');
					$("#ajax_accept").hide().show("slow",function(){ 
						setTimeout(function(){$("#login").slideUp(500);},500);
						setTimeout(function(){$('#login form')[0].submit();},1200);
					});
				}
			}
		})
	});
	$(".button")
			.ajaxStart(function(){
				$("#messages div").remove();
				$("#messages").append('<div id="ajax_load">Überprüfe Daten...</div>');
			});
});

Ok, also was wird hier gemacht?

$(document).ready(function(){...});

Wartet erst einmal bis der DOM fertig/bereit ist.

$("#login").Bounce(70);

Ist eine Funktion des Interface-Plugins für jQuery und sorgt dafür, das das Element mit der CSS-ID “login” beim Start der Seite um 70 Pixel springt.

$("#footbar").slideDown("slow");

Ebenfalls eine Animation, nur das diese bewirkt das die Fußzeile #footbar beim Start der Seite langsam hereingleitet.

	$("input").focus(function(){ 
		$(this).parent().addClass("active");
	});
	$("input").blur(function(){ 
		$(this).parent().removeClass();
	});

Sobald ein Input-Feld auf der Seite aktiviert wird (focus), bekommt dessen Eltern-Element (in diesem Fall das übergeordnete <label> die Klasse active zugewiesen. Wird das Feld wieder verlassen (blur), so wird auch die Klasse wieder entfernt. Diese Funktion dient also einfach nur zur optischen Hervorhebung des aktiven Input-Feldes.

$('#login form').submit(function(e){
		e.preventDefault();
		var username = $("#username input").attr('value');
		var password = $("#password input").attr('value');

Jetzt wirds spannend. Diese Codezeilen werden nur dann ausgefüllt, wenn das Formular(form) innerhalb der CSS-ID “#login” abgesendet (submit) wurde. In unserem Fall wird eine Funktion e gestartet. e.preventDefault(); verhindert dabei zunächst, das das Formular einfach über den Browser abgesendet wird, denn wir wollen ja eine Ajax-Anfrage starten. var username = $("#username input").attr('value'); und var password = $("#password input").attr('value'); legen uns zwei Variablen mit den derzeitigen Inhalten (value-Attribut) der Input-Felder in der CSS-ID “username” und “password” an. Ich denke bis hierhin alles relativ logisch.

		$.ajax({
			type: "POST",
			timeout: 7000,
			data: {username: username, password: password},
			url: "login",
			success: function(result) {...}

Dieser Teil beginnt eine Ajax-Abfrage. Über type: "Post" definieren wir, das es sich hierbei um eine Post-Anfrage handelt. Warum gerade Post? Nun, würden wir eine GET-Anfrage machen, so müssten wir den Benutzernamen und das Passwort in der URL übertragen, also seeeehr unsicher, daher an dieser Stelle eine POST-Anfrage.

timeout: 7000, besagt das die Anfrage nach 7 Sekunden ohne Ergebnis als fehlerhaft abbrechen würde.

data: {username: username, password: password} steckt unsere vorher angelegten Variablen für die beiden Formular-Felder in die POST-Daten für die Ajax-Anfrage, die wir dann später mit PHP bzw. CakePHP auslesen und überprüfen können.

url: "login" gibt einfach an, an welche URL die Daten überhaupt gesendet werden, hier könnte z.B. auch “check.php” stehen.

success: function(result) {...} ist der Code-Abschnitt, der bei einer erfolgreichen Ajax-Abfrage ausgeführt wird (was noch nicht heißt das die eingegebenen Formularwerte richtig waren).

if(result != "true") {...}

Dieser Textabschnitt wird ausgeführt, sobald die Ajax-Anfrage erfolgreich abgeschlossen wurde, und der Inhalt der ausgelieferten Datei nicht gleich true ist, sprich, sobald wir vom PHP-Script die Antwort bekommen haben, das die Logindaten nicht korrekt waren.

					$("#ajax_load").animate({opacity: 1.0}, 500).fadeOut(500);
					$("#messages").append('<div id="ajax_error">Anmeldung war nicht erfolgreich!</div>');
					$("#login").Shake(4);

In diesem Fall wollen wir das dem User natürlich auch ausgeben. Dafür wird nach einer Wartezeit von 500 Millisekunden div mit der CSS-ID “messages” mit dem HTML-Code <div id="ajax_error">Anmeldung war nicht erfolgreich!</div> gefüllt. Zu guter letzt wird das #login-Fenster über Shake(4) viermal hin und her gewackelt, um ein Kopfschütteln zu simulieren.

				else {
					$("#ajax_load").fadeOut(200);
					$("#messages").append('<div id="ajax_accept">Erfolgreich, sende an System...</div>');
					$("#ajax_accept").hide().show("slow",function(){ 
						setTimeout(function(){$("#login").slideUp(500);},500);
						setTimeout(function(){$('#login form')[0].submit();},1200);
					});
				}

Dieser Codeabschnitt wird ausgeführt, wenn vom Server eine andere Antwort als “false” kommt, also wenn die Logindaten korrekt waren. Dafür wird erstmal die Ladeanzeige #ajax_load (dazu später mehr) ausgeblendet und dem uns bereits bekannten #messages-div eine positive Meldung eingeworfen und über show() langsam eingefadet. setTimeout dient uns in diesem Beispiel übrigens dazu, ein Script zeitlich ein wenig zu steuern, da ansonsten die Animationen zu schnell ablaufen würden, und der Benutzer von den Ausgaben evtl. nichts mitbekommen würde.

Zum Ende hin wird das komplette Loginfeld durch slideUP("500"); vertikal zusammengerollt, und das Formular durch $('#login form')[0].submit(); auf dem ganz normalem Weg an den Server abgeschickt, denn durch die [0] vor der submit-Anweisung hebeln wir das vorher gesetzt e.PreventDefault() aus.

	$(".button")
			.ajaxStart(function(){
				$("#messages div").remove();
				$("#messages").append('<div id="ajax_load">Überprüfe Daten...</div>');
			});

Bewirkt zudem noch, das sobald unser Formular über Ajax abgefeuert wurde, alle Nachrichten im #messages-Container gelöscht werden, und im Anschluss dort eine Ladeanimation eingepackt wird.

So, das war es soweit mit dem jQuery-Code, vielleicht für den Anfänger etwas verwirrend, aber das liegt vielleicht auch an meinem evtl. nicht ganz optimalem Quellcode.

Prüfen der Daten mit CakePHP

Nun müssen wir ja auf der Serverseite die Ajaxanfrage auch prüfen und natürlich ein Ergebnis ausliefern. Mit CakePHP geht das relativ einfach, da man hiermit leicht zwischen einer normalen Browseranfrage und einer Ajax-Anfrage unterscheiden kann, man kann also beide Anfragen über ein und die selbe URL laufen lassen.

	function login() {
		$this->layout = 'login';
            if($this->RequestHandler->isAjax() == true) {
			$result = $this->User->find(array('username' => $_POST['username'],'password' => md5($_POST['password'])));
			if(!empty($result)) { echo "true"; } else { echo "false"; }
			$this->render(null,'ajax');exit;
		}
		if(!empty($this->data)) {
			$result = $this->User->find(array('username' => $this->data['User']['username'],'password' => md5($this->data['User']['password'])));
			if(!empty($result)) {
				$this->Session->write('User', $result['User']['id']);
				$this->redirect('/'.CAKE_ADMIN.'/pages/');
			} else {
				$this->flash('Falsche Logindaten','/'.CAKE_ADMIN.'/users/login');
			}
		}

Hierfür habe ich meinem User-Controller eine neue Action mit dem Namen login verpasst.

Der obere Quelltext ließt sich mit Cake gewohnt einfach. In Kurform wähle ich am Anfang des Scripts das Login-Layout aus und frage ab, ob der derzeitige Request denn eine Ajax-Anfrage ist. Danach Suche ich in der Datenbank nach dem passenden Einträgen und gebe das Ergebnis über $this->render(null,'ajax');exit; als simplen Quelltext aus, also ohne Template drumherum.

Ist es keine Ajax-Abfrage, so passiert im Prinzip genau das selbe (denn nur auf die Ajax-Abfrage können wir uns ja nicht verlassen). Allerdings wird in diesem Fall natürlich auch eine Session erzeugt, damit der User fortan auch eingeloggt bleibt.

Übrigens hat mir beim erstellen der Mini-Anwendung das Visitenkarten-Tutorial von Silvan Hagen sehr geholfen, sehr gut geschrieben und leicht zu verstehen. Die Inspiration für den Loginscreen kam von Frank Weinerth.



Kommentare zum Thema Ajax-Login mit jQuery und CakePHP:

1 | adi schrieb am 11.06.2007 um 18:55
Gravatar dieses Kommentators

wie sieht es mit der sicherheit hier aus?

2 | Christian schrieb am 11.06.2007 um 20:02
Gravatar dieses Kommentators

Eigentlich genauso wie bei einem normalen Loginfeld auch, die Daten werden im Prinzip im selben Verfahren an den Server versendet und ausgewertet. Im Prinzip ist solch ein Loginfeld grafischer Firlefanz, aber eben mein Probeobjekt um jQuery zu lernen ;)

3 | Jonny schrieb am 14.06.2007 um 13:33
Gravatar dieses Kommentators

Very nice.
Praktisch ist es ja, dass die Daten bereits vor dem Senden gehasht werden könnten. Und
sicher ist es sowieso, da der Login ja erst durch das richtige Submit erfolgen soll.

4 | tim schrieb am 22.06.2007 um 21:15
Gravatar dieses Kommentators

Genial! Danke für das Tutorial, hat mir echt weitergeholfen. Das Design ist dir gut gelungen!

5 | Benedict schrieb am 09.07.2007 um 19:06
Gravatar dieses Kommentators

Hey! Der Artikel ist wirklich gut. Arbeite mich auch gerade in jQuery ein und werd deine Artikel im jQuery Bereich mit freude weiterverfolgen.

6 | MyD schrieb am 09.09.2007 um 15:51
Gravatar dieses Kommentators

Also habe soweit alles gemacht.
Nur klappt das ganze noch nicht mit cakePHP.
und zwar nehme ich an das es an der url liegt.

meine controller fkt heisst: /index/login

in der jquery-login.js
url: “/index/login”

und in der thtml
<form method=“post” action=”<? echo $html->url(’/index/login’); ?>”>

was koennte hier falsch sein?

im controller (/index/login)

if (!empty ($this->data)) {
if($this->data[‘User’][‘username’] == ‘asdf’ && $this->data[‘User’][‘password’] == ‘asdf’) $this->redirect(’/index/admin’);
else $this->redirect(’/index/start’);

7 | Georg schrieb am 27.10.2007 um 02:52
Gravatar dieses Kommentators

Hallo Christian könntest Du bitte das Demo zum Download freigeben?
Ich versuche das Zusammenspiel zwischen html,javascript, php usw. zu begreifen.

Vielen Dank

8 | andreas schrieb am 21.12.2007 um 09:31
Gravatar dieses Kommentators

Hi,
kannst Du bitte den Quellcode zum download bereitstellen ?
Ich bin newbie bei ajax und jquery und würde diese login gerne verstehen.
Danke
Andreas

9 | Christian schrieb am 21.12.2007 um 10:15
Gravatar dieses Kommentators

Mhm, ich verstehs grad nich ganz :) Die JS-Dateien, CSS-Dateien und Grafiken können doch aus dem Beispiel bezogen werden? Den kompletten JS-Code sieht man doch zudem auch oben mit super Erklärung?

Was ich eben einfach vermeiden will ist, das hier jemand den Code unverändert übernehmen will, denn das ist kein Plugin oder dergleichen, sondern eben einfach ein Praxisbeispiel, daher ist nachbauen gerne erwünscht, aber nicht unverändertes Übernehmen :)

Wer jQuery lernen will sollte gerade am Anfang nicht mit einem fertigen Baustein anfangen, sondern natürlich auch verstehen was da überhaupt steht, oder?

10 | andreas schrieb am 21.12.2007 um 10:38
Gravatar dieses Kommentators

Mein Problem ist das ich nicht genau weiß wie die view
aussehen muss …
Die Demo scheint ja leider auch nicht mit cake gemacht zu sein, sondern einfach
php oder ?

11 | Lotta schrieb am 14.02.2008 um 23:01
Gravatar dieses Kommentators

Hallo,
habe gerade diesen Beitrag gelesen. Kann man diese Lösung mit reinem php erstellen?
Hast Du eventuell ein Bsp. Vielen Dank!

12 | andreas schrieb am 27.04.2008 um 00:23
Gravatar dieses Kommentators

$(’#login form’).submit(function(e){ e.preventDefault();

Könntest Du das viell. mal näher erklären?

13 | alfonso schrieb am 12.11.2008 um 10:50
Gravatar dieses Kommentators

Hi,

ich habe eine Frage zu der Javascript login. wie siehst mit der Session aus und wieso gibt da keine redirect auf eine neue seite? Ich habe das Problem, dass die Login Seite weiter angezeigt wird und nichts passiert. Was habe ich denn falsch gemacht?

14 | Roland schrieb am 22.02.2009 um 00:52
Gravatar dieses Kommentators

Hallo, erst ein mal danke für so ein super Tutorial.
Nun hab ich eine Frage, hoffentlich liest Du diese denn noch nach 1 1/2 Jahren.
Ich nutze Firefox 3 und SecureLogin als Addon. Wenn ich mich jetzt auf der Demo Seite mit willkürlichen username und passwort anmelden mag geht das klar nicht. Speicher ich diese aber in SecureLogin ab und drücke dann die Tastenkombination ‘alt+n’ habe ich auf ein mal Zugang zu deiner ‘test’ Seite.
Woran könnte das liegen? Habe versucht den Fehler zu finden. Erfolglos.

15 | thom schrieb am 30.03.2009 um 17:08
Gravatar dieses Kommentators

sehr interessante sache! arbeite selbst auch viel mit jquery, jedoch mehr im grafischen stil, gute arbeit! freue mich auf mehr :)

weiter so!

16 | Martin schrieb am 20.11.2009 um 22:49
Gravatar dieses Kommentators

Guten Abend! :-)

Mir gefällt das Design deines Logins! Darf man dieses kopieren? (Ich beziehe mich auf die Grafiken und CSS.) Und wenn ich schon dabei bin – wie steht es um die PSD der Header-Grafik? :-P

Grüße und ein schönes Wochenende,
Martin

17 | Chris schrieb am 27.01.2010 um 17:39
Gravatar dieses Kommentators

Hi

Nichts für ungut, aber das Skript ist überhaupt nicht sicher. Das kann jedes Kind “hacken”. Man nehme Firebug (Plugin für Firefox) und setze auf der Demo-Seite bei folgender Zeile einen Haltepunkt:
if(result != “false”) {
dann kann man einfach die Variable result auf true setzen und schon ist man drin :P

Freue mich schon auf ein sicheres Skript^^

Chris

18 | stephan schrieb am 12.02.2010 um 12:07
Gravatar dieses Kommentators

Absolut korrekt. Dem ist wohl nichts hinzuzufügen…

19 | christian schrieb am 01.04.2010 um 14:32
Gravatar dieses Kommentators

@chris: warum sollte das skript nicht sicher sein? was bringt mir es wenn ich jquery(bzw. javascript) aushebel aber serverseitig keine session angelegt wird für den user und damit das acl/auth component den user spätestens wenn er auf die weiterleitung klickt wieder auf die loginseite schickt ?!

jquery und das ganze web 2.0 ist mehr oder weniger nur ein komfortgeschichte für nutzer. stichwort pagereload etc. pp

20 | Kenlu schrieb am 29.04.2010 um 20:57
Gravatar dieses Kommentators

Hallo,
da ich phpcake nicht verwende wollte ich es wie folgt versuchen:

$getUser_sql = $db->select(‘SELECT * FROM `’ . USERS_TABLE_NAME . ‘` WHERE username=”’. $_POST[‘username’] . ‘” AND password = “’ . $_POST[‘password’] . ‘”’); $getUser = mysql_query($getUser_sql); $getUser_result = mysql_fetch_assoc($getUser); $getUser_RecordCount = mysql_num_rows($getUser);

if($getUser_RecordCount < 1){ echo ‘false’;} else { echo ‘true’;}

nur funktioniert das nicht. Da ajax die POST (username und passwort) an php nicht übergibt.

wie geht das ohne phpcake?

Kommentar-Feed für diesen Artikel


Kommentarfunktion für diesen Artikel geschlossen.



Blogsuche

RSS-Feeds

Plaste & Plastik

plasteundplastik.de - Das Geocaching-Weblog

Die Kategorien


Netz-Fundstücke


Meta / Propaganda