I've been trying to save PHP session data in a MySQL database, but can't get it to work.
For a simple example, here's code that should increment a counter with each visit. I've seen other examples, etc. but can someone please tell me why this code isn't working? (Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9 MySQL client version: 5.0.51a)
Here is the mysql database table:
CREATE TABLE IF NOT EXISTS `sessions` (
`session_ID` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`session_data` mediumblob NOT NULL,
`access` int(10) unsigned NOT NULL,
PRIMARY KEY (`session_ID`),
KEY `access` (`access`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
And the PHP code (just plug in your db credentials):
<?PHP
function mysession_open()
{
global $sdbc; // Session Database Connection
if ($sdbc) {
return true;
} else {
return false;
}
}
function mysession_close()
{
global $sdbc;
return mysqli_close($sdbc);
}
function mysession_read($session_id)
{
global $sdbc;
$session_id = mysqli_real_escape_string($sdbc, $session_id);
$sql_sel = "SELECT session_data FROM sessions WHERE session_id = '$session_id'";
$data_sel = mysqli_query($sdbc, $sql_sel);
$row_sel = mysqli_fetch_array($data_sel);
if (isset($row_sel['session_data'])) {
return $row_sel['session_data'];
} else {
return '';
}
}
function mysession_write($session_id, $session_data)
{
global $sdbc;
$access = time();
$session_id = mysqli_real_escape_string($sdbc, $session_id);
$access = mysqli_real_escape_string($sdbc, $access);
$session_data = mysqli_real_escape_string($sdbc, $session_data);
$sql_write = "REPLACE INTO sessions (session_ID, session_data, access) " .
"VALUES ('$session_id', '$session_data', '$access')";
return mysqli_query($sdbc, $sql_write);
}
function mysession_destroy($session_id)
{
global $sdbc;
$session_id = mysqli_real_escape_string($sdbc, $session_id);
return mysqli_query($sdbc, $sql_del);
}
function mysession_gc($max)
{
global $sdbc;
$old = time() - $max;
$old = mysqli_real_escape_string($sdbc, $old);
$sql_old = "DELETE FROM sessions WHERE access < '$old'";
return mysqli_query($sdbc, $sql_old);
}
global $sdbc;
$sdbc = mysqli_connect('localhost', '...', '...', '...') or die('Could not connect to SDBC');
session_set_save_handler('mysession_open','mysession_close','mysession_read','mysession_write','mysession_destroy','mysession_gc');
session_start();
if (isset($_SESSION['counter'])) {
echo "counter is already set and it is " . $_SESSION['counter'] . '<br />';
$_SESSION['counter']++;
} else {
echo "counter is not set. setting to 1<br />";
$_SESSION['counter'] = 1;
}
echo "<br />Dumping SESSION data:<br />";
var_dump($_SESSION);
session_write_close();
?>
Thanks in advance for your help.
If you comment out the session_set_save_handler line of code, it works fine (it increments). But using the save handler it does not.
None of your query calls have any error checking. Instead of blindly assuming the database portion works, do some basic error checking at each stage, e.g:
function mysession_write($session_id, $session_data) {
global $sdbc;
[...snip...]
$stmt = mysqli_query($sdbc, $sql_write);
if ($stmt === FALSE) {
error_log("Failed to write session $session_id: " . mysqli_error($sdbc);
}
return($stmt);
}
There's only way way for a query to succeed, but zillions of ways to fail.
From the manual:
"Warning
As of PHP 5.0.5 the write and close handlers are called after object destruction and therefore cannot use objects or throw exceptions. The object destructors can however use sessions.
It is possible to call session_write_close() from the destructor to solve this chicken and egg problem. "
Related
I've been trying to track down a bug in my software for months now, to no success. It all comes down to one update query in PHP PDO seeming to run, with the correct data and yet it doesn't seem to update as "rowcount" returns 0.
Seems entirely random, 99% of the time it runs perfectly. 1% just doesn't update and I've literally no idea why.
For reference, here's the code in case someone spots me doing something really dumb. The part that is having issues is where it's updating the "saved_sessions" table.
// if they have a stay logged in cookie log them in
function stay_logged_in()
{
if (isset($_COOKIE['session']))
{
$session_check = $this->db->run("SELECT `session_id`, `device-id`, `user_id`, `expires` FROM `saved_sessions` WHERE `session_id` = ? AND `expires` > NOW()", array($_COOKIE['session']))->fetch();
if ($session_check)
{
// login then
$this->user_details = $this->db->run("SELECT ".$this::$user_sql_fields." FROM `users` WHERE `user_id` = ?", array($session_check['user_id']))->fetch();
$this->check_banned();
// update IP address and last login
$this->db->run("UPDATE `users` SET `ip` = ?, `last_login` = ? WHERE `user_id` = ?", array(core::$ip, core::$date, $this->user_details['user_id']));
// update their stay logged in cookie with new details
$generated_session = md5(time() . mt_rand() . $this->user_details['user_id'] . $_SERVER['HTTP_USER_AGENT']);
$expires_date = new DateTime('now');
$expires_date->add(new DateInterval('P30D'));
$update_session_sql = "UPDATE
`saved_sessions`
SET
`session_id` = ?,
`expires` = ?
WHERE
`session_id` = ? AND `user_id` = ?";
$update_session_db = $this->db->run($update_session_sql, array($generated_session, $expires_date->format('Y-m-d H:i:s'), $_COOKIE['session'], $session_check['user_id']));
$check_update = $update_session_db->rowcount();
// database was updated, so we can update the cookie
if($check_update == 1)
{
$cookie_domain = false; // allows cookies for localhost dev env
$secure = 0; // allows cookies for localhost dev env
if (!empty($this->core->config('cookie_domain')))
{
$cookie_domain = $this->core->config('cookie_domain');
$secure = 1;
}
setcookie('session', $generated_session, time()+$this->cookie_length, '/', $cookie_domain, $secure);
}
else
{
// logging for me to attempt to check the details match up (which they always seem to do!)
error_log("Couldn't update saved session for user_id " . $session_check['user_id'] . "\n" . "Current user session data: \n" . print_r($session_check, true) . "\nUser cookie data: " . $_COOKIE['session'] . "\n Database info: " . print_r($update_session_db, true));
}
$this->register_session($generated_session, $session_check['device-id']);
return true;
}
else
{
setcookie('session', "", time()-60, '/');
setcookie('device', "", time()-60, '/');
return false;
}
}
else
{
return false;
}
}
Issue resolved - see: https://stackoverflow.com/a/14719452/1174295
--
I've come across a problem within (at least) Google Chrome and Safari.
Upon the first attempt at logging in, the user is not redirected. The session is created, but it is almost as if it is not detected, and takes the user back to the index page. Upon a second attempt, the correct redirect is issued and the user is taken to the correct page.
The script works fine in Firefox, and I have checked extensively to see if the correct data is being returned, which it is. I've searched and I've searched and I've searched, but unfortunately nothing of use has cropped up.
Access.php - User logging in
<?php
session_start();
ob_start();
include_once('db.class.php');
include_once('register.class.php');
include_once('login.class.php');
$db = null;
$reg = null;
$log = null;
$db = new Database();
$log = new Login($db, null, null, null, null, null, null);
if (isset($_SESSION['login'])) {
$log->redirectUser($_SESSION['login']);
}
include_once('includes/header.html');
?>
Some HTML...
<?php
if (isset($_POST['logsub'])) {
$db = new Database();
$log = new Login($db, $_POST['email'], $_POST['pass']);
$validation = &$log->validate();
if(empty($validation)) {
$log->redirectUser($_SESSION['login']);
} else {
echo "<div id='error'><div class='box-error'><p style='font-weight: bold'>The following errors occured...</p><ul>";
for ($i = 0; $i < count($validation); $i++) {
echo "<li>" . $log->getErrorMessage($validation[$i]) . "</li>";
}
echo "</ul></div></div>";
}
}
?>
Login.class.php - Login class
// Validate the credentials given
public function validateLogin() {
// Hash the plain text password
$this->hashedPass = $this->hashPassword();
try {
$query = $this->dbcon->prepare("SELECT Login_ID, Login_Email, Login_Password FROM Login WHERE Login_Email = :email AND Login_Password = :pass");
$query->bindParam(':email', $this->email, PDO::PARAM_STR);
$query->bindParam(':pass', $this->hashedPass, PDO::PARAM_STR);
$query->execute();
$fetch = $query->fetch(PDO::FETCH_NUM);
$this->loginid = $fetch[0];
// If a match is found, create a session storing the login_id for the user
if ($query->rowCount() == 1) {
$_SESSION['login'] = $this->loginid;
session_write_close();
} else {
return LOG_ERR_NO_MATCH;
}
} catch (PDOException $e) {
$this->dbcon->rollback();
echo "Error: " . $e->getMessage();
}
}
// Fetch the customer ID
private function getCustId() {
try {
$query = $this->dbcon->prepare("SELECT Customer.Cust_ID FROM Customer JOIN Login ON Customer.Login_ID = Login.Login_ID WHERE Customer.Login_ID = :loginid");
$query->bindParam(':loginid', $this->loginid, PDO::PARAM_INT);
$query->execute();
$fetch = $query->fetch(PDO::FETCH_NUM);
return $fetch[0];
} catch (PDOException $e) {
$this->dbcon->rollback();
echo "Error: " . $e->getMessage();
}
}
// Check the registration progress - are they verified? paid?
// This function is used elsewhere hence the $sessionid argument
public function checkRegistration($sessionid) {
$this->loginid = $sessionid;
$this->custid = $this->getCustId();
try {
$queryVer = $this->dbcon->prepare("SELECT Cust_ID FROM Customer_Verify_Email WHERE Cust_ID = :custid");
$queryVer->bindParam(":custid", $this->custid, PDO::PARAM_INT);
$queryVer->execute();
$queryFee = $this->dbcon->prepare("SELECT Cust_ID FROM Initial_Fee_Payment WHERE Cust_ID = :custid");
$queryFee->bindParam(":custid", $this->custid, PDO::PARAM_INT);
$queryFee->execute();
// If a record exists in the verify table, return the value 1. This means the user has not yet verified their email.
if ($queryVer->rowCount() == 1) {
return 1;
} else {
// If a record does not exist in the payment table, no payment has been made. Return 2.
if ($queryFee->rowCount() == 0) {
return 2;
// Otherwise, email is verified and the payment has been made.
} else {
return 0;
}
}
} catch (PDOException $e) {
$this->dbcon->rollback();
echo "Error: " . $e->getMessage();
}
}
// Redirect the user accordingly
public function redirectUser($sessionid) {
$this->loginid = $sessionid;
$logNum = $this->checkRegistration($this->loginid);
if ($logNum == 0) {
header("Location: fbedder/details.php", true, 200);
exit();
} else if ($logNum == 1) {
header("Location: fbedder/verification.php", true, 200);
exit();
} else if ($logNum == 2) {
header("Location: fbedder/payment.php", true, 200);
exit();
}
}
Here's a link to the site: fbedder/ -> I have set-up a test account with the credentials -> email: test# / password: test123321
To reiterate, the problem exists only in Google Chrome and Safari (the Safari being on my iPhone) and lies purely within the logging in aspect. On the first attempt, the session will be ignored (it is created), and on the second attempt, the user will be redirected.
Any ideas? I've tried a multitude of possibilities...
-- Edit --
I know where the issue lies now.
When the redirect is called, it sends the user to the details.php page. However, this page contains the following snippet of code:
if (!isset($_SESSION['login'])) {
header("Location: fbedder/index.php");
}
Obviously what is happening, is that the session is not being detected / saved / "whatevered", and as a result is sending the user back to the index page. Is there are a way to ensure the $_SESSION is not effectively lost. I had read about this before posting here, and is why I inserted session_write_close(), but that doesn't seem to be doing the desired effect.
After diagnosing the problem being within the fact the $_SESSION variable was effectively being lost, I read up about the session_write_close() function and came across this comment:
My sessions were screwing up because I had 2 different session IDs going at once:
1 PHPSESSID cookie for domain.com
1 PHPSESSID cookie for www.domain.com
This fixed it:
//At the beginning of each page...
session_set_cookie_params (1800,"/","domain.com");
session_start();
Source: http://pt2.php.net/manual/en/function.session-write-close.php#84925
Setting the parameters resolved the issue.
Basically I have a piece of code that has a switch statement and some functions. It goes to the switch statement using a parameter given by the browser "?step=X" and then selects the appropriate function.
My problem is even when at the end of each function I specify to go to the next switch statement it never does it and somehow it becomes an infinite loop of the function that I selected with the "step=x" in the browser...
Why is getting stuck in 1 function and not iterating through them? (the code for the step is highlighted at the end of the script)
I get the output in the browser of any selected function. so It enters the switch and the selected function... but then it becomes and infinite loop because in the broswer i get 300 of the same echo statements. It is never able to iterate through them or exit the selected function.
<?php
//DB Config File
$dbFile = 'dbconfig.php';
$username = $_GET['username'];
$password = $_GET['password'];
$server = $_GET['server'];
$dbname = $_GET['dbname'];
$step = $_GET["step"];
function createfile ($dbFile) {
//Creates File and populates it.
$fOpen = fopen($dbFile, 'w');
global $username, $password, $server, $dbname;
$fString .= "<?php\n";
$fString .= "// Database Constants\n";
$fString .= "\$DB_SERVER =" . "\"" . $server . "\";\n";
$fString .= "\$DB_USER =" . "\"" . $username . "\";\n";
$fString .= "\$DB_PASS =" . "\"" . $password . "\";\n";
$fString .= "\$DB_NAME =". "\"" . $dbname . "\";\n";
$fString .= "?>";
fwrite($fOpen, $fString);
fclose($fOpen);
return true;
}
try {
$db = new PDO ('mysql:host=' .$server.';dbname='.$dbname,$username,$password);
if ($db) { //if succesful at connecting to the DB
if (file_exists($dbFile)){
if (is_readable($dbFile) && is_writable($dbFile)){
//Creates File, populates it and redirects the user
if (createfile($dbFile)) {
echo "nelxt";
stepFunction($step);
exit ();
}
} else {
echo "The file {$dbFile} cannot be accessed. Please configure the file manualy or grant Write and Read permission."; }
} else {
//Creates File, populates it and redirects the user
if (createfile($dbFile)) {
echo "next";
stepFunction($step);
exit ();
}
}
}
} catch (PDOException $e) { //Catchs error if can't connect to the db.
echo 'Connection failed: ' . $e->getMessage();
}
// Prepare SQL Statements
$IDB = $db->prepare(
"CREATE TABLE pages (
id int(11) NOT NULL auto_increment,
subject_id int(11) NOT NULL,
menu_name varchar(30) NOT NULL,
position int(3) NOT NULL,
visible tinyint(1) NOT NULL,
content text NOT NULL,
PRIMARY KEY (id)
)ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8");
$IDB2 = $db->prepare("
CREATE TABLE subjects (
id int(11) NOT NULL auto_increment,
menu_name varchar(30) NOT NULL,
position int(3) NOT NULL,
visible tinyint(1) NOT NULL,
PRIMARY KEY (id)
)ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8");
$IDB3 = $db->prepare("
CREATE TABLE users (
id int(11) NOT NULL auto_increment,
username varchar(50) NOT NULL,
hashed_password varchar(40) NOT NULL,
PRIMARY KEY (id)
)ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8");
//Set Option to True or False
if (empty ($_GET['fot']) ) {
$fOT = false;
} else { $fOT = true;
}
///////////////////////////////
// PROBLEMATIC STEP BEGINS HERE
///////////////////////////////
function createTablePages (){
global $db,$IDB;
echo "0 <br>";
stepFunction (1);
}
function createTableSubjects ($fOT){
global $db,$IDB2;
echo "1 <br>";
stepFunction (2);
}
function createTableUsers ($fOT){
global $db,$IDB3;
echo "3 <br>";
}
function stepFunction ($step,$fOT){
global $db,$IDB1,$IDB2,$step,$fOT;
switch ($step) {
case 0: echo "hola";
createTablePages ($fOT);
break;
case 1: echo "hola2";
createTableSubjects($fOT);
break;
case 2: createTableUsers ($fOT);
break;
}
}
?>
Fix
function stepFunction ($step,$fOT){
global $db,$IDB1,$IDB2,$step,$fOT;
to
function stepFunction ($step){
global $db,$IDB1,$IDB2;
You are overriding your $step variable with the global one of the same name. Thus when you come with ?step=0 you call stepFunction with 0 then it goes to createTablePages then it goes to stepFunction with 1, but is immediately replaced with 0 (because that's what the global $step's value is) and again and again...
This question already exists:
Closed 10 years ago.
Possible Duplicate:
checklogin condition issue in php
i have this quick question please,
i have this piece of code which isn't working properly, something about the syntax.. could you please help me with it?
i know it may sound stupid enough but i'm trying to understand!
Thanks!
<?php
session_start();
require_once('db.php');
include('functions.php');
if (checkLogin('1 2')) {
echo "hello ".$_SESSION['user_id']." You are now logged in.";
} else if (checkLogin('3')) {
echo "hey tst";
} else {}
?>
function checkLogin($levels)
{
if(!$_SESSION['logged_in'])
{
$access = FALSE;
}
else {
$kt = split(' ', $levels);
$query = mysql_query('SELECT Level_access FROM users WHERE ID = "'.mysql_real_escape_string($_SESSION['user_id']).'"');
$row = mysql_fetch_assoc($query);
$access = FALSE;
while(list($key,$val)=each($kt))
{
if($val==$row['Level_access'])
{//if the user level matches one of the allowed levels
$access = TRUE;
}
}
}
if($access==FALSE)
{
header("Location: login.php");
}
else {
//do nothing: continue
}
}
CREATE TABLE `users` (
`ID` int(11) NOT NULL auto_increment,
`Username` varchar(255) NOT NULL,
`Password` varchar(255) NOT NULL,
`Temp_pass` varchar(55) default NULL,
`Temp_pass_active` tinyint(1) NOT NULL default '0',
`Email` varchar(255) NOT NULL,
`Active` int(11) NOT NULL default '0',
`Level_access` int(11) NOT NULL default '2',
`Random_key` varchar(32) default NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `Username` (`Username`),
UNIQUE KEY `Email` (`Email`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Well you could simplify your checkLogin() function
function checkLogin($levels)
{
$access = false;
if (!isset($_SESSION['logged_in']) || !$_SESSION['logged_in'])
return false;
//use mysqli instead mysql
$con = new mysqli("localhost", "username", "password", "database");
$query = $con->query('SELECT Level_access FROM users WHERE ID = "'.$con->real_escape_string($_SESSION['user_id']).'"');
$row = $query->fetch_assoc();
$con->close();
if (in_array($row['Level_access'], explode(" ", $levels))) $access = true;
return $access;
}
This function should return true or false!
After that your code could look like this
session_start();
require_once('db.php');
include('functions.php');
if (checkLogin('1 2')) {
echo "hello ".$_SESSION['user_id']." You are now logged in.";
} else if (checkLogin('3')) {
echo "hey tst";
} else {
header("Location: login.php");
}
Hope this helps you.
Your if statements need parenthesis around them:
if( checkLogin('1 2')) {
^ ^
Try this
<?php
session_start();
require_once('db.php');
include('functions.php');
if (checkLogin('1 2')) {
echo "hello ".$_SESSION['user_id']." You are now logged in.";
} else if (checkLogin('3')) {
echo "hey tst";
} else {}
?>
Run the code in your browser. You'll get an error message. Use that error message to figure out what's wrong. Repeat until you get no error messages, and the program runs as designed.
That's how we debug things in the real world.
I'm trying to protect page by making a member only area the code I use in this case is
<?php
include 'dbc.php';
page_protect();
?>
there is no error by using this code and also it just working fine
but the problem is that whenever I place the below code in the same page
the problem will happen with the iPhone, only with this device but the rest still ok, like PCs, laptop and tablet (iPad) they are all no problem
But the iPhone the problem will be that you can access to the page after login but whenever you refresh it will redirect you to the login page and ask for login again.
<?php
if(!isset($_GET['link'])){
$link = 1;
} else {
$link = $_GET['link'];
}
if ($link == 1) {
echo "";
} elseif ($link == 23) {
echo "";
} else {
echo "";
}
?>
There is no error show or anything.
my question is that is there anyway to protect the page because I need this to be member only area and the above code is very important and need to be in the page.
Thanks in advance.
here is the dbc.php sorry about that but I copied the whole script and placed here
<?php
/*************** PHP LOGIN SCRIPT V 2.3*********************
(c) Balakrishnan 2010. All Rights Reserved
Usage: This script can be used FREE of charge for any commercial or personal projects. Enjoy!
Limitations:
- This script cannot be sold.
- This script should have copyright notice intact. Dont remove it please...
- This script may not be provided for download except from its original site.
For further usage, please contact me.
/******************** MAIN SETTINGS - PHP LOGIN SCRIPT V2.1 **********************
Please complete wherever marked xxxxxxxxx
/************* MYSQL DATABASE SETTINGS *****************
1. Specify Database name in $dbname
2. MySQL host (localhost or remotehost)
3. MySQL user name with ALL previleges assigned.
4. MySQL password
Note: If you use cpanel, the name will be like account_database
*************************************************************/
define ("DB_HOST", "xxxxxx"); // set database host
define ("DB_USER", "xxxxxx"); // set database user
define ("DB_PASS","xxxxxxx"); // set database password
define ("DB_NAME","xxxxxx"); // set database name
$link = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die("Couldn't make connection.");
$db = mysql_select_db(DB_NAME, $link) or die("Couldn't select database");
/* Registration Type (Automatic or Manual)
1 -> Automatic Registration (Users will receive activation code and they will be automatically approved after clicking activation link)
0 -> Manual Approval (Users will not receive activation code and you will need to approve every user manually)
*/
$user_registration = 1; // set 0 or 1
define("COOKIE_TIME_OUT", 10); //specify cookie timeout in days (default is 10 days)
define('SALT_LENGTH', 9); // salt for password
//define ("ADMIN_NAME", "admin"); // sp
/* Specify user levels */
define ("ADMIN_LEVEL", 5);
define ("USER_LEVEL", 1);
define ("GUEST_LEVEL", 0);
/*************** reCAPTCHA KEYS****************/
$publickey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$privatekey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
/**** PAGE PROTECT CODE ********************************
This code protects pages to only logged in users. If users have not logged in then it will redirect to login page.
If you want to add a new page and want to login protect, COPY this from this to END marker.
Remember this code must be placed on very top of any html or php page.
********************************************************/
function page_protect() {
session_start();
global $db;
/* Secure against Session Hijacking by checking user agent */
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
logout();
exit;
}
}
// before we allow sessions, we need to check authentication key - ckey and ctime stored in database
/* If session not set, check for cookies set by Remember me */
if (!isset($_SESSION['user_id']) && !isset($_SESSION['user_name']) )
{
if(isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])){
/* we double check cookie expiry time against stored in database */
$cookie_user_id = filter($_COOKIE['user_id']);
$rs_ctime = mysql_query("select `ckey`,`ctime` from `users` where `id` ='$cookie_user_id'") or die(mysql_error());
list($ckey,$ctime) = mysql_fetch_row($rs_ctime);
// coookie expiry
if( (time() - $ctime) > 60*60*24*COOKIE_TIME_OUT) {
logout();
}
/* Security check with untrusted cookies - dont trust value stored in cookie.
/* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login*/
if( !empty($ckey) && is_numeric($_COOKIE['user_id']) && isUserID($_COOKIE['user_name']) && $_COOKIE['user_key'] == sha1($ckey) ) {
session_regenerate_id(); //against session fixation attacks.
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['user_name'] = $_COOKIE['user_name'];
/* query user level from database instead of storing in cookies */
list($user_level) = mysql_fetch_row(mysql_query("select user_level from users where id='$_SESSION[user_id]'"));
$_SESSION['user_level'] = $user_level;
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
} else {
logout();
}
} else {
header("Location: login.php");
exit();
}
}
}
function filter($data) {
$data = trim(htmlentities(strip_tags($data)));
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = mysql_real_escape_string($data);
return $data;
}
function EncodeURL($url)
{
$new = strtolower(ereg_replace(' ','_',$url));
return($new);
}
function DecodeURL($url)
{
$new = ucwords(ereg_replace('_',' ',$url));
return($new);
}
function ChopStr($str, $len)
{
if (strlen($str) < $len)
return $str;
$str = substr($str,0,$len);
if ($spc_pos = strrpos($str," "))
$str = substr($str,0,$spc_pos);
return $str . "...";
}
function isEmail($email){
return preg_match('/^\S+#[\w\d.-]{2,}\.[\w]{2,6}$/iU', $email) ? TRUE : FALSE;
}
function isUserID($username)
{
if (preg_match('/^[a-z\d_]{5,20}$/i', $username)) {
return true;
} else {
return false;
}
}
function isURL($url)
{
if (preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url)) {
return true;
} else {
return false;
}
}
function checkPwd($x,$y)
{
if(empty($x) || empty($y) ) { return false; }
if (strlen($x) < 4 || strlen($y) < 4) { return false; }
if (strcmp($x,$y) != 0) {
return false;
}
return true;
}
function GenPwd($length = 7)
{
$password = "";
$possible = "0123456789bcdfghjkmnpqrstvwxyz"; //no vowels
$i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
if (!strstr($password, $char)) {
$password .= $char;
$i++;
}
}
return $password;
}
function GenKey($length = 7)
{
$password = "";
$possible = "0123456789abcdefghijkmnopqrstuvwxyz";
$i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
if (!strstr($password, $char)) {
$password .= $char;
$i++;
}
}
return $password;
}
function logout()
{
global $db;
session_start();
if(isset($_SESSION['user_id']) || isset($_COOKIE['user_id'])) {
mysql_query("update `users`
set `ckey`= '', `ctime`= ''
where `id`='$_SESSION[user_id]' OR `id` = '$_COOKIE[user_id]'") or die(mysql_error());
}
/************ Delete the sessions****************/
unset($_SESSION['user_id']);
unset($_SESSION['user_name']);
unset($_SESSION['user_level']);
unset($_SESSION['HTTP_USER_AGENT']);
session_unset();
session_destroy();
/* Delete the cookies*******************/
setcookie("user_id", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
setcookie("user_name", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
setcookie("user_key", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
header("Location: login.php");
}
// Password and salt generation
function PwdHash($pwd, $salt = null)
{
if ($salt === null) {
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
}
else {
$salt = substr($salt, 0, SALT_LENGTH);
}
return $salt . sha1($pwd . $salt);
}
function checkAdmin() {
if($_SESSION['user_level'] == ADMIN_LEVEL) {
return 1;
} else { return 0 ;
}
}
?>
An alternative to your current protect script, ive made it without cookies:
<?php
//A basic login and session script I just whacked up
session_start();
/**
* cleanit cleans unwanted chars
*
* #param string $input
* #return clean string containing only a-zA-Z0-9.,_ -
*/
function cleanit($input){
return preg_replace('/[^a-zA-Z0-9\.,_ -]/s', '', $input);
}
/**
* auth function called on each page you want protected
*
* #param $_SESSION['user_name'] $logged_in_user
* #param $_SESSION['user_hash'] $hash
* #param $_POST['user'] (when logging in) $username
* #param $_POST['pass'] (when logging in) $password
* #param [login|check|logout] function control $exe
* #return $_SESSION gets set returns LOGGED_IN|ERROR:MULTI:USERS|ACCESS_DENIDE|ACCESS_TIMEOUT|ACCESS_LOGGED_OUT
*/
function auth($logged_in_user,$hash,$username,$password,$exe) {
global $db;
if ($exe=='login') {
//LOGIN////////////////////////////////////////////////
$result = mysql_query('SELECT * from users where username="'.cleanit(mysql_real_escape_string($username)).'" and password="'.cleanit(mysql_real_escape_string(sha1($password))).'"',$db);
$num = mysql_num_rows($result);
if($num=='1') {
session_regenerate_id();
$_SESSION['user_status']='LOGGED_IN';
while ($row = mysql_fetch_array($result)) {
$_SESSION['user_id'] = $row['id'];
$_SESSION['user_name'] = $row['username'];
$_SESSION['user_hash'] = md5($_SERVER['REMOTE_ADDR']);
$_SESSION['user_ip'] = cleanit($_SERVER['REMOTE_ADDR']);
$_SESSION['user_date'] = time();
$_SESSION['user_level'] = cleanit($row['user_level']);
}
$result2 = mysql_query('REPLACE into users values ("'.mysql_real_escape_string($_SESSION['user_id']).'","'.mysql_real_escape_string($_SESSION['user_name']).'","'.mysql_real_escape_string(sha1($password)).'","'.mysql_real_escape_string($_SESSION['user_hash']).'","'.mysql_real_escape_string($_SESSION['user_ip']).'","'.mysql_real_escape_string($_SESSION['user_date']).'","'.mysql_real_escape_string($_SESSION['user_level']).'")',$db);
$return = 'LOGGED_IN';
return $return;
}elseif($num >='2') {
$result = mysql_query('DELETE from users where username="'.mysql_real_escape_string($username).'" and password="'.mysql_real_escape_string(sha1($password)).'"');
$error = 'ERROR:MULTI:USERS';
return $error;
}else {
unset($_SESSION['user_id']);
unset($_SESSION['user_name']);
unset($_SESSION['user_hash']);
unset($_SESSION['user_ip']);
unset($_SESSION['user_date']);
unset($_SESSION['user_level']);
$_SESSION['user_status']=='';
session_destroy();
$return = 'ACCESS_DENIDE';
return $return;
}
return $return;
}
if($exe=='check') {
//CHECK////////////////////////////////////////////
$result = mysql_query('SELECT hash,ip,user_date from users where username="'.mysql_real_escape_string($logged_in_user).'" and hash="'.mysql_real_escape_string($hash).'"',$db);
if(mysql_num_rows($result)==1) {
$rows = mysql_fetch_row($result);
$timeout = (time()-1800);
if($rows[2]<=$timeout){auth("","","","","logout");
return'ACCESS_TIMEOUT';
}
if($hash==$rows[0] && $_SERVER['REMOTE_ADDR']==$rows[1]) {
$return = 'LOGGED_IN';
mysql_query('UPDATE users set user_date="'.time().'"',$db);
return $return;
}else {
session_regenerate_id();
$return = 'ACCESS_DENIDE';
return $return;
}
}else{
session_regenerate_id();
$return = $_SESSION['user_status'];
return $return;
}
}
if($exe=='logout') {
//LOGOUT///////////////////////////////////////////
unset($_SESSION['user_id']);
unset($_SESSION['user_name']);
unset($_SESSION['user_hash']);
unset($_SESSION['user_ip']);
unset($_SESSION['user_date']);
unset($_SESSION['user_level']);
unset($_SESSION['user_status']);
session_destroy();
session_regenerate_id();
$return = 'ACCESS_LOGGED_OUT';
return $return;
}
if($exe=='') {
//BLANK////////////////////////////////////////////
unset($_SESSION['user_id']);
unset($_SESSION['user_name']);
unset($_SESSION['user_hash']);
unset($_SESSION['user_ip']);
unset($_SESSION['user_date']);
unset($_SESSION['user_level']);
unset($_SESSION['user_status']);
session_destroy();
session_regenerate_id();
$return = 'FUNCTION.ERROR:DO.MISSING';
return $return;
}
return $return;
}
/*
SQL
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL DEFAULT '',
`password` varchar(45) NOT NULL DEFAULT '',
`hash` varchar(45) NOT NULL DEFAULT '',
`ip` varchar(45) NOT NULL DEFAULT '',
`user_date` varchar(45) NOT NULL DEFAULT '',
`user_level` varchar(45) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `users` (`id`, `username`, `password`, `hash`, `ip`, `user_date`, `user_level`) VALUES
(1, 'admin', '6c7ca345f63f835cb353ff15bd6c5e052ec08e7a', 'f528764d624db129b32c21fbca0cb8d6', '127.0.0.1', '1306757011', '1');
admin/admin1
*/
//Usage
/*--------------------------------*/
//login page
session_start();
if(isset($_REQUEST['user']) && isset($_REQUEST['pass'])){
$user=cleanit($_REQUEST['user']);
$pass=cleanit($_REQUEST['pass']);
$_SESSION['user_status'] = auth("","",$user,$pass,"login");
header('members.php');
}else{
//Show login form
}
/*--------------------------------*/
/*--------------------------------*/
//Members page
session_start();
//Checks login on each page request put this on all pages you want to protect
$_SESSION['session_status'] = #auth($_SESSION['user_name'],$_SESSION['user_hash'],"","","check");
if($_SESSION['session_status']=='LOGGED_IN'){
//Logged in norm user
}elseif($_SESSION['session_status']=='LOGGED_IN' && $_SESSION['user_level']==1){
//Logged in as admin
}else{
//Logged out
}
/*--------------------------------*/
//Logout
if($_REQUEST['do']=='logout'){
auth("","","","","logout");
header('Location: index.php');
}
?>
This is a comment posted here for better formatting.
You have to read the man pages on session_ functions work! Doing so will save you time and aggravation. Many here have given you hints on the possible source of your problem. For one, you cannot have ANY output whatsoever before session_start(). For 2, make sure you have error reporting turned on in your environnement.
if(!isset($_GET['link'])){
$link = 1;
} else {
$link = $_GET['link'];
}
if ($link == 1) {
echo "";
} elseif ($link == 23) {
echo "";
} else {
echo "";
}
This snippet at the top of your post will always make your script fail if you try to echo anything whatsoever. Again, friendly advice, take 15 minutes of your time and read the manual. You will have access to much more valuable first-hand information on those aspects of your work than by posting here out of laziness to get a quick fix. Then again, I probably am not the first one to tell you this.