我正在尝试了解会话以及如何使用它们来显示用户数据并授予对站点区域的访问权限等...
我在配置文件的开头session_start();
,然后继续连接到数据库等...
然后我有一个 User.php 类,如下所示:
<?php
include('Password.php');
class User extends Password{
private $db;
function __construct($db){
parent::__construct();
$this->_db = $db;
}
public function is_logged_in(){
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true){
return true;
}
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM members WHERE username = :username');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['password'];
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed) == 1){
$_SESSION['loggedin'] = true;
return true;
}
}
public function logout(){
session_destroy();
}
}
?>
当我使用 var_dump($_SESSION);
返回时:
array(1) { ["loggedin"]=> bool(true) }
我想做的是有类似"你好,'(人员用户名)'欢迎来到网站的'(基本,高级,管理员等...)'区域"。
所以我想做一些像$_SESSION['memberID'], $_SESSION['username'], $_SESSION['level']
所以。。。首先,我是否在寻找正确的区域来做这种事情(User.php),并且修改我已经拥有的任何内容是否允许我这样做,或者我是否需要创建另一个函数并查询数据库等......如果我做$_SESSION['username'] = 'mee';
这样的事情,那么它将显示"我",但我想做的是获取登录的任何用户的用户名。
*如果这毫无意义或令人困惑,请提前道歉,iv 一段时间以来一直在试图解决这个问题,但实际上我所做的一切都没有意义 - 大脑超载:/
出于安全目的,谨慎的做法是查询数据库以获取对应用程序中受限区域的每个后续请求。这可以通过简单地将用户 ID 存储在会话变量中并通过存储的用户 ID 的每个请求拉取用户数据来实现。这样,如果在用户仍登录时撤销访问权限,系统将正确响应
此功能可以像这样实现:
// after successfully getting user by the provided username/password
$_SESSION['logged_in_user_id'] = $user['id']
现在,在每个请求中,您只需检查:
if (isset($_SESSION['logged_in_user_id'])) {
$currentUser = (new User())->find($_SESSION['logged_in_user_id']);
}
在您的用户模型中,您可以执行以下操作:
public function find($id) {
try {
$stmt = $this->_db->prepare('SELECT name, address, user_level, email FROM members WHERE id = :id');
$stmt->execute(array('id' => $id));
$row = $stmt->fetchAll();
$user = new self();
$user->fill($row[0]);
return $user;
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
} catch (Exception $e) {}
return null;
}
public function fill(array $data) {
foreach ($data as $key => $value) {
$this->$key = $value;
}
return $this;
}
要注销用户:
unset($_SESSION['logged_in_user_id']);
此方法还有一个额外的好处,即将敏感的用户数据排除在服务器上的纯文本会话文件之外,任何有权访问该框的人都可以读取这些文件。
现在,对于会话,您确实需要牢记会话劫持的可能性,但这是另一个讨论,并且有大量的PHP软件包可以帮助防止此漏洞。
如果您不关心安全性,只是想让它以尽可能少的努力工作(不推荐),您可以简单地将用户数据数组存储在会话中并使用您需要的任何内容:
登录代码:
public function login($username,$password){
if ($user = $this->getWithCredentials($username, $password) {
$_SESSION['logged_in_user'] = json_encode($user);
return true;
}
return false;
}
public function getWithCredentials($username, $password) {
try {
$hashedPassword = $this->myPasswordHashAlgorithm($password);
$stmt = $this->_db->prepare('SELECT id, name, address, email FROM members WHERE username = :username AND password = :password');
$stmt->execute(array('username' => $username, 'password' => $hashedPassword));
$row = $stmt->fetch();
return $row;
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
} catch (Exception $e) {}
return null;
}
然后,要获取后续请求的用户数据,请执行以下操作:
$user = isset($_SESSION['logged_in_user']) ? json_decode($_SESSION['logged_in_user'] : null;