在
PHP笔记-用户登录&权限拦截说明
这篇博文中设置Cookie时用的是数据库的用户id。这样有问题,用户可以随意改动ID,从而获取不同的用户权限。
这里我们更新下,增加点安全性。构造safe包
内容如下:
CookieAndSession.php
<?php
namespace safe;
class CookieAndSession{
public $cookie;
public $userId;
public $browser;
public $os;
public $timeToLive;
}
CookieTool.php
<?php
namespace safe;
class CookieTool{
protected function generateKey(): string{
$length = 32;
$retKey = "";
for ($i = 0; $i < $length; $i++)
{
$retKey .= chr(mt_rand(33, 126));
}
return $retKey;
}
protected function getIPAddress(): string{
$ipaddress = "";
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
protected function getBrowser($agent): string{
$browserAgent = "";
if(strstr($agent, 'MSIE')) {
$browserAgent="Internet Explorer";
}
else if(strstr($agent, 'Opera')) {
$browserAgent="Opera";
}
else if(strstr($agent, 'Firefox')) {
$browserAgent="Firefox";
}
else if(strstr($agent, 'Chrome')) {
$browserAgent = "Chrome";
}
else if(strstr($agent, 'Safari')) {
$browserAgent = "Safari";
}
else{
$browserAgent = "unknown";
}
return $browserAgent;
}
protected function getPlatform($agent): string{
$agent = strtolower($agent);
$platform = "";
if(strstr($agent, 'win')) {
$platform="windows";
}
else if(strstr($agent, 'linux')) {
$platform = "linux";
}
else{
$platform = "unknown";
}
return $platform;
}
protected function getMacAddress(): string{
$MAC = exec('getmac');
print_r($MAC);
$MAC = strtok($MAC, ' ');
return $MAC;
}
public function printCookieArray(){
global $cookieAndSessionArray;
print_r($cookieAndSessionArray);
}
public function setCookieByUserId($userId){
$userToken = $this->generateKey();
$browserAgent = $this->getBrowser($_SERVER['HTTP_USER_AGENT']);
$platform = $this->getPlatform($_SERVER['HTTP_USER_AGENT']);
$cookieAndSession = new CookieAndSession();
$cookieAndSession->cookie = $userToken;
$cookieAndSession->userId = $userId;
$cookieAndSession->browser = $browserAgent;
$cookieAndSession->os = $platform;
$cookieAndSession->timeToLive = 24 * 60 * 60;
@session_start();
$_SESSION["user"] = serialize($cookieAndSession);
setcookie('userToken',$userToken ,time() + 1 * 24 * 3600);
}
}
因为这里我用的是自定义MVC框架,在每次加载的时候,会调用如下start函数:
public static function start(){
self::setPath();
self::setConfig();
self::setSafe();
self::setUrl();
self::setAutoLoad();
self::setDispatch();
}
其中setSafe()就是新加的,作用是加载对应的php文件
private static function setSafe(){
$files = self::getAllFile(SAFE_PATH);
foreach($files as $file){
if(file_exists($file)){
include $file;
}
}
}
其中getAllfile是获取当前目录下的所有文件,如下:
private static function getAllFile($dir): array{
$retArray = array();
if(!is_dir($dir))
return $retArray;
$files = scandir($dir);
foreach ($files as $file){
$tmpFile = $dir . "/" . $file;
if(!is_dir($tmpFile)){
array_push($retArray, $dir . "/" . $file);
}
}
return $retArray;
}
其中SAFE_PATH如下:
?ROOT_PATH在index.php中定义的,如下:
index.php
<?php
define("ROOT_PATH", str_replace("\\", "/", dirname(__DIR__)) . "/");
include ROOT_PATH . "core/App.php";
\core\App::start();
当用户点击登录后:
其userToken就为随机数了
后台登录校验是这样的:
public function check(){
$useName = trim($_POST["userName"]);
$password = trim($_POST["password"]);
$captcha = trim($_POST["captcha"]);
......
......
......
$cookieTool = new CookieTool();
$cookieTool->setCookieByUserId($user['user_id']);
$this->success("登录成功", '', 'dashboard', "index");
}
?权限拦截如下:
public function __construct(){
include VENDOR_PATH . "smarty/Smarty.class.php";
$this->smarty = new \Smarty();
$this->smarty->template_dir = APP_PATH . P . "/view/";
$this->smarty->compile_dir = RESOURCES_PATH . "views";
if(strtolower(C) != "privilege"){
if(isset($_COOKIE['userToken'])){
@session_start();
$obj = unserialize($_SESSION["user"]);
if(strcmp($_COOKIE['userToken'], $obj->cookie) != 0){
$this->error("未登录,请先登录", "user", "privilege", "login");
}
$userModel = new UserModel();
$user = $userModel->getById((int)$obj->userId);
if($user){
return;
}
}
$this->error("未登录,请先登录", "user", "privilege", "login");
}
}
|