我目前正在为我的网站创建自己的论坛,我已经阅读了很多关于cookie /会话身份验证的主题,我想我知道存在的攻击等。我认为它不是100%安全,但我试图尽可能安全。
我目前正在将cookie存储在cookie中,并且我知道有些人可能会遇到问题,但我会改变以检查IP的前2个块。我不认为这会成为一个问题,因为瑞典有95%的人拥有宽带而很少改变IP。
我真正不安全的是session_start,我稍后需要表单等等,实现它的最佳实践是什么?我很确定我做的那件事非常错误。
非常感谢任何投入!
类
class user2
{
private $db = null;
private $cookie_salt = '!!PLonSIMDSAM35324dfg5DAUSHODNASDJ353NMASDSA&%&A/SD&HASNJDdfghAS&DGIHYAUSDNA3535SDFASDF%A3532dfgsdfggsdg53532535SDGIASYDU';
var $user_ip = false;
var $user_id = false;
var $user_username = false;
var $cookie_identifier = false;
var $user_logged_in = false;
function __construct()
{
global $mysql_server;
global $mysql_user;
global $mysql_password;
global $mysql_database_name;
$this->db = new database($mysql_server, $mysql_user, $mysql_password, $mysql_database_name, true);
$this->checkUserAuthentication();
}
public function Login($input_username, $input_user_password)
{
// If empty parameters return false
if (empty($input_username) || empty($input_user_password))
{
return false;
}
$user_login = $this->db->q("SELECT user_id, username FROM `forum_user` WHERE username = ? AND password = ? LIMIT 1", 'ss' , $input_username, $input_user_password);
if ($user_login != false)
{
$this->user_ip = $_SERVER['REMOTE_ADDR'];
$this->user_id = $user_login[0]['user_id'];
$this->user_username = $user_login[0]['username'];
if($this->initiateSessionCookie() == true)
{
$this->user_logged_in = true;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
private function initiateSessionCookie()
{
// Delete old sessions from this user or USE REPLACE instead
$this->db->q("DELETE FROM `forum_session` WHERE userid = ?", 'i' , $this->user_id);
$identifier = md5($this->cookie_salt . md5($this->user_username . $this->user_ip) . $this->cookie_salt);
$token = md5($this->generateToken());
$timeout = time() + 60 * 60 * 24 * 7; // 7 days
$timeout_minutes = 10080; // 7 days
$init_session = $this->db->q("INSERT INTO forum_session SET session = ?
, token = ?
, userid = ?
, sess_start = now()
, last_activity = now()
, sess_expire = DATE_ADD(curdate(),INTERVAL ? MINUTE)
, ip = ?", 'ssiis' , $identifier, $token, $this->user_id, $timeout_minutes, $this->user_ip);
if($init_session != false) {
setcookie('auth', "$identifier:$token", $timeout);
return true;
}
else {
return false;
}
}
private function generateToken()
{
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz!#&";
for($i = 1; $i <= 20; $i++)
{
$rand_number = rand(0, 59);
$random_string .= $chars[$rand_number];
}
return $random_string;
}
private function checkUserAuthentication()
{
$this->user_logged_in = false;
list($_cookie_identifier, $_cookie_token) = explode(':', $_COOKIE['auth']);
if(ctype_alnum($_cookie_identifier) && ctype_alnum($_cookie_token))
{
$_cookie_data['identifier'] = $_cookie_identifier;
$_cookie_data['token'] = $_cookie_token;
}
else
{
return false;
}
$auth_user = $this->db->q("SELECT *
FROM forum_session a
LEFT JOIN
forum_user b ON a.userid = b.user_id
WHERE
a.session = ? AND
a.token = ?
LIMIT 1", 'ss' , $_cookie_data['identifier'], $_cookie_data['token']);
if($auth_user != false)
{
if(time() > strtotime($auth_user[0]['sess_expire']))
{
return false;
}
if($_cookie_data['identifier'] == md5($this->cookie_salt . md5($auth_user[0]['username'] . $_SERVER['REMOTE_ADDR']) . $this->cookie_salt))
{
$this->user_logged_in = true;
$this->user_id = $auth_user[0]['user_id'];
$this->user_username = $auth_user[0]['username'];
$this->user_ip = $_SERVER['REMOTE_ADDR'];
return true;
// TODO list
// Renew token every 5 min?
// Renew cookie expire date
// Renew session expire date
}
else
{
return false;
}
}
else
{
return false;
}
}
public function isUserLoggedIn()
{
return $this->user_logged_in;
}
}
我在论坛的所有页面中都包含的会话处理程序。
require_once('classes/user2.class.php');
$user = new User2();
session_start();
答案 0 :(得分:0)
为什么不从控制器(?)中的session_start()开始。
如果不需要,我会在控制器中使用一个方法,以避免双重session_start:
class controller {
$sStarted = false;
function sStart() {
if (!$this->sStarted) {
session_start();
$this->sStarted = true;
}
问候 /吨