You are not logged in.

  • Login

1

Wednesday, September 9th 2009, 3:24pm

Session Login auf Cookie umbauen

Hallo,

Für eine Vereins Homepage habe ich ein kleines Login Script.
Soweit läuft alles, allerdings beschweren sich nun die Member das sie sich nach 24 Stunden neu einloggen müssen.
Genau, mein Login Script spiechert die IP. Nun würde ich das ganze gerne auf Cookie umbauen. Ich habe mich bereits daran versucht aber bin voll gescheitert.

Ich weiss, es ist nicht das Sicherste und Beste, aber es hat immer seine Dienste getan.
Hier mal mein Code, evtl hat wer Tips bezüglich Cookie oder gar nen Komplettes Script auf seinem Rechner.

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Prüfen ob eingeloggt
function chkonline()
  {
    $anfrage  = "SELECT `user_id` FROM `users_online` WHERE `ip` = '".$_SERVER['REMOTE_ADDR']."' AND `session` = '".session_id()."'";
    $ergebnis = mysql_query($anfrage);
    if($ergebnis !== false)
    {
      $anz    = mysql_num_rows($ergebnis);
      if ($anz == 0)
      {
        return false;
      }
      $zeile  = mysql_fetch_row($ergebnis);
      return $zeile[0];
    }
    else
    {
      return false;
    }
  }
 
// Switch abfrage im Template ob User eingeloggt ist und bereiche sehen kann. Stammt aus dem phpbb2 bzw 3
if ( chkonline() )
{
	$template->assign_block_vars('switch_user_logged_out', array());
}
else
{
	$template->assign_block_vars('switch_user_logged_in', array());
}


Und hier das eigentliche Login Script

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
if ( isset($_POST['submit']) )
	{
		$username = income($_POST['username']);
		$password = $_POST['password'];
		$message = false;
 
  	$sql  = "SELECT `id`, `username`, `passwort` FROM `users` WHERE `username` = '".$_POST['username']."'";
  	$result = db_query($sql);
	$row = mysql_fetch_assoc($result);
 
	if ( !$_POST['username'] )
	{
		$message .= $lang['no_username']. '<br />';
		$fehler = true;
	}
	if ( !$_POST['password'] )
	{
		$message .= $lang['no_password']. '<br />';
		$fehler = true;
	}
	if ( !$_POST['username'] == $row['username'] )
	{
		$message .= $lang['no_login_user'] . '<br />';
		$fehler = true;
	}
 
	if ( !isset($fehler) )
	{
		if(chkonline() === false)
      	{
		$sql  = "DELETE FROM `users_online` WHERE `user_id` = '".$row['user_id']."' LIMIT 1";
		$result = db_query($sql);
		$sql  = "INSERT INTO `users_online` VALUES('".$row['id']."','".$row['id']."','".$_SERVER['REMOTE_ADDR']."','".$session_id."')";
		$result = db_query($sql);
		$message .= $lang['login_ok'] . '<br />';
	  }
	  else
	  {
		  $message .= $lang['login_true'] . '<br />';
	  }
	}
}

2

Wednesday, September 9th 2009, 9:26pm

na ist doch wunderbar...

in der chkonline#4 musst du nur die IP Adresse als Einschränkung weglassen und $_COOKIE['deinkey'] statt der session_id() verwenden

und in der login methode #33 verwendest du als $session_id eine zufällige Zeichenkette, die du auch als Cookie speichest

PHP Quellcode

1
2
$session_id = uniqid(rand(), true);
setcookie('deinkey', $sessionid, strtotime('+1 year'));


Der Rückgabewert der Funktion ist übrigens 32 Byte groß - es bietet sich also an deine Tabellenspalte mit char(32) auszustatten.
Mehr Informationen zu random Funktion: Gutes Passwort mit PHP erstellen

3

Thursday, October 8th 2009, 8:05pm

HuHu,

Also ich habe das jetzt mal geändert. Beim 1 Login hat er den cookie angelegt, nach dem löschen des cookies will er aber keinen mehr anlegen.
Mein sql spalte habe ich auf TEXT 255 geändert da der cookie key was länger ist.

PHP Quellcode

1
2
$user_key = md5($pass.$user).'-irc-'.time().'-'.$user;
setcookie('point', $user_key, time()+(3600*24*100));


Wie gesagt, beim 1 mal klappte es, nach löschen des cookies legt er keine mehr an.

lg
Klari22

This post has been edited 1 times, last edit by "Klari22" (Oct 8th 2009, 8:50pm)


4

Thursday, October 8th 2009, 8:45pm

nach dem Löschen des Cookie legt er keinen mehr an? Wie meinst du das?
Das Cookie wird natürlich nur angelegt, wenn du auf dich neu mit Benutzernamen und Passwort anmeldest.

Der Syntax Fehler bei dir hast sich bestimmt nur beim kopieren eingeschlichen, oder?

5

Thursday, October 8th 2009, 8:48pm

HuHu,

Jep, ist nur ein Fehler vom Kopieren.
Genau das ist es, ich melde mich neu an, der user_key wird auch in der Datenbank eingetragen, aber er legt keine Cookies mehr von dieser Seite an.

Wie gesagt, ich habe den coockie im FF manuell gelöscht um den neuen key zu testen.

This post has been edited 1 times, last edit by "Klari22" (Oct 8th 2009, 8:54pm)


6

Thursday, October 8th 2009, 8:55pm

Das heißt dein Code hat bisher einmal funktioniert und danach nie wieder?
Klingt unwahrscheinlich.

Kann es sein, dass Fehler passieren die du nicht anzeigst?
Zum Beispiel das insert in #33 - was geschieht, wenn die userid schon "online" ist?

was hältst du von einem

SQL Code

1
... ON DUPLICATE KEY UPDATE session_id = $session_id, ip = $ip;

7

Thursday, October 8th 2009, 8:59pm

Doch, ein fehler wird mir angezeigt.

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\site\templates_c\%%FA^FA4^FA44DF90%%page_header.htm.php:7) in C:\xampp\htdocs/site\class\user.php on line 145
Linie 145 ist zei Zeile wo er den Coockie sendet.

Ne, Duplicat ist nicht vorhanden, der wird aus der DB entfernt falls ein eintrag vorhanden ist

Hier mal ein wenig mehr vom Code

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$DB->set_sql('SELECT * FROM ircd_users_online
						 WHERE username =:1');
				$DB->execute($user);
				$row = $DB->fetch_assoc();
				$DB->free();
 
				if ( $row != false )
				{
					$DB->set_sql('DELETE FROM ircd_users_online WHERE username =:1  LIMIT 1');
					$DB->execute($user);
					$DB->free();
				}
 
				$user_key = md5($pass.$user).'-irc-'.time().'-'.$user;
				setcookie('point', $user_key, time()+(3600*24*100));
 
				$user_array = array();
				$user_array['user_id']			= $row['user_id'];
				$user_array['username'] 		= (string) $user;
				$user_array['user_key'] 		= (string) $user_key;
 
				$DB->set_sql('INSERT INTO ircd_users_online ' . $DB->syntax_built(SQL_INSERT, $user_array));
				$DB->execute();
				$DB->free();

8

Thursday, October 8th 2009, 9:07pm

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\site\templates_c\%%FA^FA4^FA44DF90%%page_header.htm.php:7) in C:\xampp\htdocs/site\class\user.php on line 145


na da ist doch der Fehler.
Wenn du schon eine Ausgabe an den Browser gesendet hast (via echo oder eben über ein Template), dann ist es zu spät um noch ein Cookie hinterherzusenden.
Du musst die vorherige Ausgabe entfernen

9

Thursday, October 8th 2009, 9:10pm

Ah, jetzt ist die Frage, wie bekomme ich die vorherige Ausgabe netfernt?
Cookie gelöscht, seite neu geladen, db manuell geleert und den cache und templates_c Ordner geleert.

10

Thursday, October 8th 2009, 9:14pm

Du rufst vermutlich die display Methode von smarty auf, bevor du setcookie aufrufst. Die Reihenfolge ist das Problem.

du kannst ja statt dem setcookie() mal ein die() machen - du wirst sehen, dass der Browser dennoch irgendwas darstellt. Zu dem Zeitpunkt muss aber noch alles leer sein.

11

Thursday, October 8th 2009, 9:21pm

Ah, er sendet den ganzen Header mit.

PHP Quellcode

1
$Core->page_header('Login');


Habs mal nach unten gesetzt

PHP Quellcode

1
2
$User->user_login();
$Core->page_header('Login');


Nu läuft es, besten Dank.

12

Thursday, October 8th 2009, 9:51pm

Hm ok, Cookie setzt er zwar jetzt, aber ich kann ihn nicht auslesen

PHP Quellcode

1
var_dump($_COOKIE['point']);


Die Ausgabe ist NULL

13

Friday, October 9th 2009, 11:59am

HuHu,

Der Umbau des alten Login Script treibt mich in den Wahnsinn.
Ich bekomme es nun absolut nicht hin zu prüfen ob eingelogt oder nicht und im Template dann mit {if $LOGGED_IN} und {if $LOGGED_OUT} Bereiche auszublenden bzw einzublenden.

Ich habe jetzt die ganze Nacht an dem Script gesessen und binn am Ende.
Kann mir jemand das Script bitte verfolständigen oder zumindest einen Anstoß geben wie es aussehen müsste?

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public function login_status()
	{
		global $DB, $Smarty, $Core;
 
		$user_cookie = $_COOKIE['point'];
		$DB->set_sql('SELECT * FROM ircd_users_online
					 WHERE user_key =:1');
		$DB->execute($user_cookie);
		$login_row = $DB->fetch_assoc();
		$DB->free();
 
		if ( $login_row )
		{
 
		}
		else
		{
 
		}
 
	}
 
$Smarty->assign(array(
			'PAGE_HEADER'			=> $this->config['sitename'] . ' : ' . $this->config['description'] . ' &bull; ' . $title,
			'IS_LOGED'				=> $User->login_status('user_key') == 1 ? true : false,
			'U_LOGIN_SEND'			=> 'login.php?mode=login',
        ));

14

Friday, October 9th 2009, 6:24pm

Zum Verständnis wie Cookies funktionieren

das funktioniert nicht:

PHP Quellcode

1
2
setCookie('foo', 'x');
echo $_COOKIE['foo'];


das funktioniert:

PHP Quellcode

1
2
3
setCookie('foo', 'x');
// pagerefresh 
echo $_COOKIE['foo'];


das ist ein legitimer Workaround

PHP Quellcode

1
2
3
setCookie('foo', 'x');
$_COOKIE['foo'] = 'x';
echo $_COOKIE['foo'];


schau dir mal mit Firefox über Privatsphäre > Cookies an, ob das Cookie wirklich gesetzt ist und mit welchen Attributen (Domain, Pfad, Gültigkeit, ...) es gespeichert wurde
Wenn Firefox sagt es ist da, und Domain/Pfad existieren, dann muss auch PHP darauf Zugriff haben.

Außerdem ein nützliches Firefox Addon: FireCookie (in Kombination mit Firebug)

15

Friday, October 9th 2009, 6:44pm

HuHu,

Cookie wird mittlerweile gesetzt, und auslesen kann ich den auch, war noch nen kleiner Fehler noch im Script.

Ist nur noch das Problem mit dem Loggin Status wie ich vorhin beschrieben habe um einzente Teile im Template auszublenden.

Ich hatte ja Anfangs vor nur das Login System umzubauen da es absolut nicht OOP war und total unübersichtlich, mittlerweile stell ich die ganze Seite um. Neuer Code, Klassen ect. Das einzige was noch fehlt ist eben bestimmte Bereiche im Template ausblenden wenn eingeloggt/ausgeloggt. Vorher nutze ich noch die Template Engine vom phpBB3 da klappte alles, jetzt ist es Smarty und ein "einfacher Umbau gestallet sich schwer.

This post has been edited 2 times, last edit by "Klari22" (Oct 10th 2009, 1:24am)


16

Saturday, October 10th 2009, 2:36pm

Ich habe das Gefühl, dass du mit der Code-Reihenfolge ein paar Probleme hast, oder?

Wenn du im Template {$IS_LOGED} prüfst, dann solltest du problemlos Bereiche ein- und ausblenden.

17

Sunday, October 11th 2009, 12:45am

HuHu,

Jep, die Code Reienfolge machte mir schon immer Probleme.
Leider nein, mit {$IS_LOGED} wird es auch ausgeblendet wenn ich nicht eingeloggt bin.

18

Sunday, October 11th 2009, 5:37pm

Hallo,

Ok, mit

PHP Quellcode

1
2
3
4
5
6
7
8
if ( $login_row )
		{
			return true;
		}
		else
		{
			return false;
		}


klappt es dann doch. Ein Problem habe ich noch, unzwar den Usernamen oder die ID in den Scripten verwenden. Gestern klappte alles, heute will es nun nicht mehr.

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Login Userdaten sammeln
	public function user_data()
	{
		global $DB, $Smarty, $Core, $User;
 
		if ($User->login_status() == false )
		{
			$DB->set_sql('SELECT * 
						 FROM ircd_users
						 WHERE user_id = 1');
			$DB->execute();
			$userdata = $DB->fetch_assoc();
			$DB->free();
		}
		else
		{
			$user_cookie = $_COOKIE['point'];
			$DB->set_sql('SELECT o.*, u.* 
						 FROM ircd_users_online AS o,
						 ircd_users AS u
						 WHERE o.user_key =:1
						 AND o.username = u.username');
			$DB->execute($user_cookie);
			$userdata = $DB->fetch_assoc();
			$DB->free();
 
		}
 
	}


Wenni ch die Daten jetzt mit $Core->user_data['username']; oder echo $userdata['username']; ausgeben lassenwill geht garnix.
Wie gesagt, gestern lief es noch.

19

Sunday, October 11th 2009, 8:15pm

wo liegt denn das Problem?
Kommt nichts aus der Datenbank? Einfach mal mit print_r ausgeben.

Oder kommt nichts im Template an? Wo geschieht denn das assign? Um festzustellen ob du mit der Reihenfolge durcheinander kommst, mache jeweils DEBUG Ausgaben
* in das assign.
* In die Datenbankabfrage
* in das smarty display

Similar threads

Social bookmarks