webForumDet fria alternativet

mvc och session

24 svar · 1 806 visningar · startad av tanten

tantenMedlem sedan nov. 20051 658 inlägg
#1

Kan man göra så här över huvudtaget? Jag försöker få ihop något som gör att det krävs att scriptet inte körs igång förrän användaren är identifierad och som är en enda person.
Tacksam för tips på hur man bör göra i stället.

<?php
session_start();
//Jag vill kolla om sessionen är satt
if(!isset($_SESSION['sess_id']))
{
$_SESSION['sess_user']="";
$_SESSION['sess_pass']=""; 
}
// fungerar utan session
require '../includes/init.php';
$guestbook = new guestbook;
$arrPosts = $guestbook->fetchPosts();
$view = new view('guestbook.phtml');
$view->setTitle('Funderingar');
$view->posts = $arrPosts;
$view->compile();
?>
MarkusHelinMedlem sedan nov. 200741 inlägg
#2

if(!isset($_SESSION['sess_id']))
{
exit;
}

något sådant du tänkt dig?

tantenMedlem sedan nov. 20051 658 inlägg
#3

MarkusHelin skrev:

if(!isset($_SESSION['sess_id']))
{
exit;
}

något sådant du tänkt dig?

Egentligen så vet jag inte vad jag har tänkt mig. Det är så nytt för mig det här...
Nu har jag fått till mer utskrifter på errors och har då upptäckt att min databaskoppling inte hittar tabellen och får undefined index redan på sidan innan.
Jag har försökt följa tipsen som cOla ger här : http://blog.c0la.se/search?search=login
men ser inte vad som kan vara fel på det jag gjort, eller...?

<?php
error_reporting(E_ALL);
//session_start;{
//$_SESSION['sess_user'] = $_POST['user'];
//$_SESSION['sess_pass'] = $_POST['pass']; 
//$_SESSION['sess_id'] = session_id(); 
//}
$db = new PDO('mysql:host=localhost;dbname=xxx', 'xxx', 'xxx');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); 

$login = $db->prepare('SELECT id, user FROM members WHERE user < ? AND pass = ?');
$login->execute(array($_POST['user'], $_POST['pass']));
if ($member = $login->fetch()) 
 
{
echo <<<LOGG
<form action="guestbook.php" method="post">
<p>Användarnamn:<br />
<input type="text" name="user" value="$user" /></p>
<p>Lösenord:<br />
<input type="password" name="pass" value="$pass" /></p>
<p><input type="Submit" name="Submit" value="Logga in" /> </p>
</form>
LOGG;
}
?>

Eftersom jag inte kommit så långt i scriptet så vet jag inte heller om resten av det fungerar och sessionen har jag kommenterat bort så länge.

**red/**ser nu att jag lyckats få bort isset med mera. Så himla trött efter att ha suttit många timmar och försökt, så jag fortsätter i morgon...

aasahMedlem sedan mars 20033 451 inlägg
#4

Här är en till som är så trött att ögonen nästan går i kors, så bara en kommentar... Jag tvivlar på att felet du pratar om ligger här, men jag gissar att följande rad inte (heller) är rätt:

$login = $db->prepare('SELECT id, user FROM members WHERE user < ? AND pass = ?');

Vill du inte kolla att det finns en användare som har exakt det inskrivna namnet? I så fall borde det stå:

$login = $db->prepare('SELECT id, user FROM members WHERE user = ? AND pass = ?');

('<' bytt mot '=')

tantenMedlem sedan nov. 20051 658 inlägg
#5

Självklart har du rätt aasah :) Var jag som hade ändrat till < när jag hade varit i manualen och kopierat utan att reflektera. Men det fungerar inte med = heller.
Men det är egentligen inte det som är problemet.
Problemet finns fortfarande i filen jag skrev i mitt första inlägg.
För även om jag ändrar den till det som MarkusHelin skrev så körs skriptet.
Så egentligen vill jag tillbaka till ursprungsfrågan.
Går det att använda session överhuvud taget för att få åtminstone en blank sida om man surfar direkt till guestbook.php? Eller ska jag försöka med något annat?

tantenMedlem sedan nov. 20051 658 inlägg
#6

Nu fick jag stopp på det med

session_start();
if(!isset($_SESSION['sess_id'])){}
else 
{
echo 'du är inte inloggad';	
exit;
}

Ska se nu om jag får igång index-sidan också...och om det fungerar då också :OO

aasahMedlem sedan mars 20033 451 inlägg
#7

Du måste ha session_start() överst på alla sidor du vill kolla/använda sessionsvariablerna på.

tantenMedlem sedan nov. 20051 658 inlägg
#8

Det tycks ha blivit en nödlösning...
Om jag surfar direkt till guestbook.php så börjar Explorer tugga utan att det händer någonting, inte ens efter 10minuter.
FF visar:
Firefox har upptäckt att servern dirigerar om förfrågan om den här platsen på ett sätt som omöjliggör ett slutförande...
Så syftet med att man inte ska se sidan fungerar om man inte är inloggad.

Loggar jag in så fungerar det helt OK, men har då en notice som säger
Notice: A session had already been started - ignoring session_start() in /customers/xxx/xxx/httpd.www/xxx/includes/init.php on line 12.
Men det går att deleta och inserta i databasen, vilket också är det enda syftet med sidan.. (det är ingen gästbok!)... så tillsvidare får det vara så.

Inloggningsfilen misslyckades jag med när jag använde PDO och gick därför tillbaka till det gamla sättet med mysql-connect.
Så jag fortsätter försöka hitta en bättre lösning.

I dag hittade jag äntligen någonting som börjar likna någonting, classer, för PDO och login, där de flesta av kommentarerna var skrivna på spanska... suck!
Får se om jag kan få ut någonting av det ändå...

FuelMedlem sedan okt. 20001 325 inlägg
#9

God Jul!

<?php
class db
{
	/*** Declare instance ***/
	private static $instance = NULL;
	
	/**
	*
	* the constructor is set to private so
	* so nobody can create a new instance using new
	*
	*/
	private function __construct()
	{
	  /*** maybe set the db name here later ***/
	}
	
	/**
	*
	* Return DB instance or create intitial connection
	*
	* @return object (PDO)
	*
	* @access public
	*
	*/
	public static function getInstance()
	{
		if (!self::$instance)
		{
		    self::$instance = new PDO("mysql:host=localhost;dbname=xxxxxxxx", 'xxxxxxxx', 'xxxxxxxx');;
		    self::$instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		}
		return self::$instance;
	}
	
	private function __clone()
	{
		
	}
}
?>
<?php
if ($_POST['login'])
{
	unset($username,$password,$user_status,$pass_status);
	
	if (isset($_POST['username']) && (preg_match ("/^([a-z0-9_-]+)$/i", $_POST['username']) && strlen($_POST['username']) > 4))
	{
		$username = $_POST['username'];
		$user_status = "ok";
	}
	else
	{
		$user_status = "Username must be..";
	}
	
	if (isset($_POST['password']) && (preg_match ("/^([a-z0-9_-]+)$/i", $_POST['password']) && strlen($_POST['password']) > 7))
	{
		$password = $_POST['password'];
		$pass_status = "ok";
	}
	else
	{
		$pass_status = "Password must be..";
	}
	
	if (($user_status == "ok") && ($pass_status == "ok"))
	{
		try
		{
			$result = DB::getInstance()->query("SELECT * FROM " . TBL_PREFIX ."_admins WHERE admin_username = '" . $username . "' AND admin_password = '" . $password . "'");
	
			if (count($result) > 0)
			{
		    	foreach($result as $row)
		    	{
		    		$_SESSION['logged'] = "1";
		    		$_SESSION['user_id'] = $row['admin_userid'];
		    		// blahblah..
		    		header("location: index.php");
		    		exit;
		    	}
		    }
			else
			{
				//log_this();
				$login_status = "This user doesnt exist in DB, this event has been logged.";
			}
		}
		catch(PDOException $e)
		{
		    echo $e->getMessage();
		}
	}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="sv">
	<head>

		<meta http-equiv="pragma" content="no-cache" />
		<meta http-equiv="cache-control" content="no-cache" />
		
		<link type="text/css" href="login.css" rel="stylesheet" />
		<script type="text/javascript" src="login.js"></script>
		
		<title>Login</title>
		
	</head>
	<body>
	
		<h1>Login</h1>
		
		<?php if (isset($login_status)) { echo "<p class=\"error\">" . $login_status . "</p>"; } ?>
		
		<form action="" method="post">
			
			<p>
				<label for="username">Username:</label><br />
				<?php if (isset($user_status) != "ok") { echo "<span class=\"error\">" . $user_status . "</span><br />"; } ?>
				<input type="text" name="username" id="username" value="<?php echo $_POST['username']; ?>" />
			</p>
			
			<p>
				<label for="password">Password:</label><br />
				<?php if (isset($pass_status) != "ok") { echo "<span class=\"error\">" . $pass_status . "</span><br />"; } ?>
				<input type="password" name="password" id="password" value="" />
			</p>
			
			<p>
				<input type="submit" name="login" id="login" value="Login" />
			</p>
		
		</form>
	
	</body>
</html>

Jag skrev koden nyss.. funkar för mig.. ( inte klassen, den kommer från en artikel )

<?php
session_start();
include("dbclass.php");
if(!isset($_SESSION['logged']))
{
	include(MY_INCLUDE_PATH . "/login.php");
	exit;
}
?>
<h1>Hemliga labans sida</h1>
<p>Julpyssel</p>
colioneMedlem sedan juni 20013 386 inlägg
#10

Ska du använda prepared statements bör du även sätta:

self::$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

I getInstance()

aasahMedlem sedan mars 20033 451 inlägg
#11

colione skrev:

Ska du använda prepared statements bör du även sätta:

self::$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

I getInstance()

Som gör vadå?

colioneMedlem sedan juni 20013 386 inlägg
#12

http://netevil.org/blog/2006/apr/using-pdo-mysql

Plus att det hela blir lite snabbare.

tantenMedlem sedan nov. 20051 658 inlägg
#13

God Jul du också Fuel :bire ... men det är väl lite tidigt...

Jag har tagit en annan riktning nu. Min nödlösning får fungera tills vidare så att han kan använda det.
Under tiden försöker jag arbeta med filerna inne i mvc.
Jag har lyckats få ihop en inloggning. Men det är med många säkerhetsrisker och en del av filerna vet jag inte hur jag ska få ihop. Men det får jag ta senare.
Tar en sak i taget
Anledningen att jag valde prepared var för Olas diskussion runt det på sin blog.
Vet inte om det finns något annat som är bättre.
så här ser min admin.php ut nu i mappen models

class admin
{
	protected $db = NULL;

	public function __construct()
	{
		$this->db = db::getInstance();
	}
	public function fetchUser($id)
	{
		$sqlSelect  = "SELECT id, user ";
		$sqlSelect .= "FROM members ";
		$sqlSelect .= "WHERE user = ? AND pass = ?";
		

		$stmtSelect = $this->db->prepare($sqlSelect);
		$stmtSelect->execute(array($id));

		return $stmtSelect->fetch(PDO::FETCH_ASSOC);
	}
}

och även om det fungerar så finns det många frågetecken i skallen.
Förslag på något bättre?
och PDO::FETCH_ASSOC är det rätt att använda det här?

colioneMedlem sedan juni 20013 386 inlägg
#14

Jag ser inget märkbart fel i koden du har skrivit. Och prepared statements är bra iom att du minimerar risken för injections.

Vilken fång-metod to använder är ju upp till dig och vilken du känner dig bekväm med. om du vet med dig att du bara ska fånga en rad kan du ju använda limit i din sql-sats och köra en fetchAll(), då vet pdo att du har fått allt du behöver och slipper hålla kvar din fråga.

Nu ska du ha ut två kolumner, men om du nån gång bara är intresserad av en kan jag rekomendera att använda fetchColumn().

colioneMedlem sedan juni 20013 386 inlägg
#15

Ska du använda fetchAll måste du dock lägga till detta i din getInstance()

self::$instance->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
tantenMedlem sedan nov. 20051 658 inlägg
#16

Jättetack för tipsen.
Det som fick mig att undra var dessa varningar
Warning: PDOStatement::execute() [function.PDOStatement-execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp\www\gb_mvc\admin\models\admin.php on line 20

Warning: PDOStatement::execute() [function.PDOStatement-execute]: SQLSTATE[HY093]: Invalid parameter number in C:\wamp\www\gb_mvc\admin\models\admin.php on line 20

Men om jag då går över till den här filen där jag inte lagt in någon säkerhet alls än. Räcker det eller vad bör jag göra?
models/admin.php

<?php

require '../includes/init.php';
$user = ($_POST['user']);
$pass = ($_POST['pass']);

if (!empty($user) && !empty($pass))
{
	$admin = new admin;
	
}

header('Location: ../../public/guestbook.php');

själva formuläret är helt befriad från php... och ska vara det
admin.phtlml

<form method="post" action="post.php">
	<p>
		<label for="user">namnet</label>
		<input type="text" name="user" id="user" size="40" />
	</p>
	<p>
	    <label for="pass">lösen</label>
		<input type="password" name="pass" id="pass" size="40" />
	</p>	
	<p>
		<input type="submit" value="Logga in" />
	</p>
</form>

i klassen jag hittade i går fanns det med väldigt mycket av md5 base64_encode hash m.m. Förmodligen anpassat till Forum eller något annat stort, som bara känns för mycket.

colioneMedlem sedan juni 20013 386 inlägg
#17

Felet ligger i ditt execute statement du passar in en variabel vid namn id:
$stmtSelect->execute(array($id));

Det borde snarare se ut såhär:
$stmtSelect->execute(array($user,$pass));

Där $user och $pass är inloggningsinformationen du vill selecta på.

tantenMedlem sedan nov. 20051 658 inlägg
#18

Ja jag har förstått att det bör se ut så, men vill man verkligen selecta $user och $pass?
Med public function fetchUser($id) vill man väl bara checka att de stämmer.
Eller hur sjutton jag ska fråga... Men du har så bra svar...
I min select så fungerar det även med att bara ha med $sqlSelect = "SELECT id";
vilket väl egentligen borde det göra ännu säkrare, eller?

colioneMedlem sedan juni 20013 386 inlägg
#19

Det var jag som var lite otydlig. Du vill ju selecta ut id och user baserat på: WHERE user = ? AND pass = ?.

Alltså måste du skicka in lika många variabler som du har frågetecken. Vilket innebär att du måste skicka in $user och $pass. Jag tror att du har förstått, kke jag som snöade in mig på kodexemplet du postade.

Posta lite ny pseudokod på hur du vill att det ska fungera så kan jag återkomma med lite riktig kod :).

tantenMedlem sedan nov. 20051 658 inlägg
#20

Vad menar du med pseudokod? :)

Inloggningen fungerar. Men jag har ingen aning om det är säkert eller bra kodat.
Vill ju att allt ska bli så bra som möjligt från början så det bara blir att bygga vidare på det sedan.
För session har jag inte tagit tag i ännu, så att bara inloggad kommer åt guestbook.php. Vilket ju egentligen var ursprungsfrågan.
Och det är dit jag vill komma, men har inte vågat blanda/lagt ihop filerna ännu. Vill se att de fungerar var för sig först.

Genererad på 386 ms · cache AV · v20260730165559-full.f96bc7eb