2010-06-10 115 views
2

我有一個奇怪的問題與PHP會話。我在我的網站上使用它們進行授權。我存儲了兩個變量 - 當前在會話中登錄了用戶的用戶名和用戶名。當我使用一個用戶名登錄時,除了註銷並使用另一個用戶名再次登錄之外,使用會話變量而不是當前用戶返回上一個用戶的ID。會話緩存問題

最奇怪的是,這隻發生在插入一些數據到數據庫時。當我直接回顯這個變量時,會顯示正確的ID,但是當我向數據庫中插入新記錄時,這個變量會發送不正確的ID。

這裏是PHP代碼我用來發送數據到數據庫:

<?php 
session_start(); 
//connect database 
require_once 'dbc.php'; 

$authorID = $_SESSION['user_id']; 
if ($authorID != 0) { 
     $content = htmlentities($_POST["answ_content"],ENT_COMPAT,'UTF-8'); 
     $dro = date('Y-m-d H:i:s'); 
     $qID = $_POST["question_ID"]; 
     $author = 'avtori'; 


     $sql="INSERT INTO comments (comment_ID, comment_post_ID, comment_author, comment_date, comment_content, user_id) 
      VALUES 
      (NULL, '$qID', '$author', '$dro', '$content', '$authorID')"; 

     $result = mysql_query($sql); 

} else { 
    echo 'error'; 
} 

?> 

任何人都可以請幫助?

這裏是註銷功能:

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: index.php"); 
} 

下面是驗證腳本:

include 'dbc.php'; 

$err = array(); 

foreach($_GET as $key => $value) { 
    $get[$key] = filter($value); //get variables are filtered. 
} 

if ($_POST['doLogin']=='Login') 
{ 

foreach($_POST as $key => $value) { 
    $data[$key] = filter($value); // post variables are filtered 
} 


$user_email = $data['usr_email']; 
$pass = $data['pwd']; 


if (strpos($user_email,'@') === false) { 
    $user_cond = "user_name='$user_email'"; 
} else { 
     $user_cond = "user_email='$user_email'"; 

} 


$result = mysql_query("SELECT `id`,`pwd`,`full_name`,`approved`,`user_level` FROM users WHERE 
      $user_cond 
      AND `banned` = '0' 
      ") or die (mysql_error()); 
$num = mysql_num_rows($result); 

    // Match row found with more than 1 results - the user is authenticated. 
    if ($num > 0) { 

    list($id,$pwd,$full_name,$approved,$user_level) = mysql_fetch_row($result); 

    if(!$approved) { 
    //$msg = urlencode("Account not activated. Please check your email for activation code"); 
    $err[] = "Account not activated. Please check your email for activation code"; 

    //header("Location: login.php?msg=$msg"); 
    //exit(); 
    } 

     //check against salt 
    if ($pwd === PwdHash($pass,substr($pwd,0,9))) { 
    // this sets session and logs user in 
     session_start(); 
     session_regenerate_id (true); //prevent against session fixation attacks. 

     // this sets variables in the session 
     $_SESSION['user_id']= $id; 
     $_SESSION['user_name'] = $full_name; 
     $_SESSION['user_level'] = $user_level; 
     $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 

     //update the timestamp and key for cookie 
     $stamp = time(); 
     $ckey = GenKey(); 
     mysql_query("update users set `ctime`='$stamp', `ckey` = '$ckey' where id='$id'") or die(mysql_error()); 

     //set a cookie 

     if(isset($_POST['remember'])){ 
        setcookie("user_id", $_SESSION['user_id'], time()+60*60*24*COOKIE_TIME_OUT, "/"); 
        setcookie("user_key", sha1($ckey), time()+60*60*24*COOKIE_TIME_OUT, "/"); 
        setcookie("user_name",$_SESSION['user_name'], time()+60*60*24*COOKIE_TIME_OUT, "/"); 
        } 
     if(empty($err)){    
      header("Location: myaccount.php"); 
     } 
     } 
     else 
     { 
     //$msg = urlencode("Invalid Login. Please try again with correct user email and password. "); 
     $err[] = "Invalid Login. Please try again with correct user email and password."; 
     //header("Location: login.php?msg=$msg"); 
     } 
    } else { 
     $err[] = "Error - Invalid login. No such user exists"; 
     }  
} 
+0

請告訴我們你如何執行註銷。 – Palantir 2010-06-10 12:29:06

+0

'htmlentities'不適合再次保護SQL注入(如果它是你正在使用它的)。使用'mysql_real_escape_string',爲參數化查詢構建器準備好語句。 – Gumbo 2010-06-10 12:30:13

+0

哦,你如何驗證你的用戶? – Gumbo 2010-06-10 12:30:51

回答

3

殺死我有多少人崗代碼容易SQL injection

<?php 
$content = htmlentities($_POST["answ_content"],ENT_COMPAT,'UTF-8'); 
     //^Attack vector 
$dro = date('Y-m-d H:i:s'); 
$qID = $_POST["question_ID"]; 
    //^Attack vector 
$author = 'avtori'; 

$sql="INSERT INTO comments (comment_ID, comment_post_ID, comment_author, comment_date, comment_content, user_id) 
     VALUES 
     (NULL, '$qID', '$author', '$dro', '$content', '$authorID')"; 
?> 

Sanitize your database inputs

0

您可以使用session_regenerate_id來確保使用一個新的會話ID和摧毀舊的:

session_start(); 
if ($userIsAuthentic) { 
    session_regenerate_id(true); 
} 

如果你不使用PHP 5.1.0或更高版本,你可以使用這個等價的噸至替代缺失delete_old_session參數:

session_start(); 
if ($userIsAuthentic) { 
    $_SESSION = array(); 
    session_destroy(); 
    session_write_close(); 
    session_start(); 
    session_regenerate_id(); 
} 
+0

什麼是$ userIsAuthentic變量? – 2010-06-10 12:36:41

+0

'$ userIsAuthentic'旨在成爲一個變量,它保存當前用戶是否可信的狀態。 – Gumbo 2010-06-10 13:02:22

+0

session_regenerate_id似乎並不是解決方案... – 2010-06-10 13:07:22

0

嘗試從軌道的摧毀了會議:session_destroy

調用它,用核武器炸他們的會話cookie,立即停止腳本,並引導用戶登錄頁面。他們將在那裏獲得新的會話並正確登錄。