Ut och inloggningskontroll i php.

Tråden skapades och har fått 7 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Sundsvall
  • 2007-05-24 13:01

Hej!

Hur gör man för att kontrollera om en användare som vill visa en sida är inloggad?
Jag skriver så här men inte får det att funka:

session_start();
 
         if (!isset($_SESSION['sess_user'])){ 
         
               header("Location: adm_login.php"); 
         } 
   

Och hur kan jag kontrollera att en användare har verkligen loggat ut och sessionerna är förstörda efteråt?

Så här har jag gjort på en sida:

På inloggningssidan:

<?
session_start();
header("Cache-control: private");

if (isset($_POST['submit']))
{
	require_once('obj/dbconnect.php');
			
	$sqlstr = "SELECT * FROM users WHERE uloginname='".strtolower($_POST['username'])."' AND upassword='".md5($_POST['password'])."'";
	$result=mysql_query($sqlstr) or die (mysql_error());
	
	if (mysql_num_rows($result)==1)
	{					 
		$_SESSION['session_username'] = $_POST['username'];
		$_SESSION['session_password'] = $_POST['password'];
		//session life
		
		header("Location: admin2.php");		
	}
	else
	{ 
		echo "Kan inte logga in dig för det uppstod problem med de uppgifter du angett.<br />Det kan vara så enkelt att du skrev fel eller så är ditt konto ej aktiverat.";
				
		$_SESSION['session_username'] = FALSE;
		$_SESSION['session_password'] = FALSE;
	}
}
?>

På det skyddade sidorna:

session_start();
	header("Cache-control: private"); //IE 6 Fix

	require_once('obj/dbconnect.php');

	$sqlstr = "SELECT * FROM users WHERE uloginname='".strtolower($_SESSION['session_username'])."' AND upassword='".md5($_SESSION['session_password'])."'";
	$result=mysql_query($sqlstr);
				
	// Check the Result
	if (mysql_num_rows($result)!=1)
	{
		header("Location: admin.php");
	}
  • Medlem
  • Sundsvall
  • 2007-05-24 14:57

Hmm...

1) Vad har du i sidan private?

2) require_once('obj/dbconnect.php'); ???
är det filen som innehåller kopplingsuppgifter till servern och databasen?

3) Vad har du i din users tabell?

4) Måste jag ha $_SESSION['session_username'] = FALSE;
$_SESSION['session_password'] = FALSE;

  • Medlem
  • Sundsvall
  • 2007-05-24 15:02

Vad tycker du om detta då?

<?php
// startar sessionen
session_start();

// om ingen session finns med rätt användarnamn och lösenord visas inloggningssidan igen
if (!isset($_SESSION["inloggning"]) || $_SESSION["inloggning"] !== true) {
header("Location: login.php");
exit;
}

// om sessionen finns är inloggningen korrekt och då visas sidinnehållet nedan:
?>
Ursprungligen av Banaz:

2) require_once('obj/dbconnect.php'); ???
är det filen som innehåller kopplingsuppgifter till servern och databasen?

4) Måste jag ha $_SESSION['session_username'] = FALSE;
$_SESSION['session_password'] = FALSE;

2: Ja, i PHP är det vanligt att man har en fil som allra minst initierar vilken databas man vill använda sig utav, vilken host den ligger hos och vilket användarnamn och lösenord som krävs för att få access dit. Samt kör en mysql_connect(). Sedan kallar man in den filen när i de filer man behöver använda sig utav databasen. dbconnect.php, config.php och db.php(?) brukar vara vanliga namn på sådana filer som sparar nödvändig databas-uppkoppling i olika variablar.

4: Det är en funktion som gör koden mer säker. Om du inte angav rätt användarnamn och lösenords kombination så ska du inte ha en session som säger att du har ett användarnamn och/eller lösenord.

Ursprungligen av Mattias Hedman:

Så här har jag gjort på en sida:

På inloggningssidan:

...

På det skyddade sidorna:

...

Det där är inte helt bra. Vad skulle hända om jag angav följande som användarnamn: abc' AND 1=0 UNION SELECT 'foobar\' AND 1=1 --' AS username, 'abc' AS password --

Där foobar är ett känt användarnamn, vilket inte brukar vara svårt att få tag på.

Jo, det som händer är att vi gör en dubbel SQL-injection, vi injectar koden för att få användarnamnet satt till vår andra injection, som ser till att returnera precis en rad, vilket ju var kravet som skulle uppfyllas.

Vad är lösningen? Se till att ha GPC magic quotes avslaget, och escapea strängar som ska in i databasen med mysql_real_escape_string och casta tal till int eller float. Eller kör med prepared statements.

  • Medlem
  • Stockholm
  • 2007-10-09 21:32

yep. escaping är en förutsättning så fort den breda massan kan mata in något som ska in i en query..

Bör också nämnas att

if (!isset($_SESSION['sess_user']))

är absolut för klent för att kolla en inloggning. Du behöver alltid kolla anvnamn & lösen ifrån din session eller cookie variabel mot databasen/filen där du har användardata, (samt ha lösen och ev annan användardata krypterad).

Jag har gjort så här att min auktoriseringsrutin körs i en funktion (med några underfunktioner) så det enda jag behöver köra på mina script sidor är:

$anvlevel = auktfunk($anvnamn,$losen,$aktivitet) or die(include "login.php");

1) om ovanstående påstående är falskt så hämtas ju login
2) från login postas anvnamn, lösen samt aktivitet (i det här fallet logga in)

I funktionen:
3) Om aktivitet är logga ut, så skriver vi skräp över cookies, nollar session och sätter falskt.
4) Om aktivitet är logga in och anvnamn och lösen skickats med funktionen betraktas detta som en ny login, oavsett tidigare status.
5) Uppgifterna kollas mot databas som sätter en användarnivå. (eller sätter falskt)
6) Om aktivitet är ingen eller annan än logga in/logga ut så kollas om session eller cookie finns. (beroende på konfiguration)
7) Om användaruppgifter finns i session eller cookie så kollas detta mot databas som sätter en användarnivå. (eller sätter falskt)
8) En roundup check med lite extra säkerhetsrutiner körs (t ex referer, antal försök och lite annan överkurs) om vi stöter på problem här så sätter vi falskt och rensar ev data som i punkt 3 ovan, alternativt erbjuder att skicka lösen till mail eller i vissa fall skriver en ban i databasen, osv..
9) Vi returnerar resultatet (falskt eller en användarnivå)

Jag vet inte om du tycker det verkar vara komplicerat men i praktiken är hela paketet ganska slimt, säg 30 rader, och när man väl fått huvudet runt den här sortens upplägg är det grymt skönt att kunna luta sig mot och lätt att felsöka. En annan poäng är att det är lätt att haka på specialarfunktioner som hänger ihop med användare och deras roller.

Och användarnivåvariabeln du får ut använder du naturligtvis till att filtera innehållet. Osv.

1
Bevaka tråden