c86f08c325
Co-Authored-By: Claude Code <noreply@anthropic.com>
89 lines
2.5 KiB
PHP
89 lines
2.5 KiB
PHP
<?php
|
||
/**
|
||
* Session 鉴权中间件
|
||
* 所有接口(登录/找回密码除外)均需通过 requireLogin() / checkPermission() 校验。
|
||
* 写类接口还必须通过 checkAjax()(要求 X-Requested-With: XMLHttpRequest)。
|
||
*/
|
||
require_once __DIR__ . '/db.php';
|
||
require_once __DIR__ . '/response.php';
|
||
require_once __DIR__ . '/security.php';
|
||
|
||
/**
|
||
* 启动 Session(批次1 起经 security.php 加固:httponly + samesite=Lax + HTTPS secure)
|
||
* 兼容既有调用方式,行为不变,仅 cookie 属性增强(REV-SEC-4/REV-8)
|
||
*/
|
||
function startSession()
|
||
{
|
||
startSessionSecure();
|
||
}
|
||
|
||
/** 校验写类接口的 Ajax 头 */
|
||
function checkAjax()
|
||
{
|
||
if (($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') !== 'XMLHttpRequest') {
|
||
Response::error('非法请求', 400);
|
||
}
|
||
}
|
||
|
||
/** 校验是否已登录,未登录返回 401 */
|
||
function requireLogin()
|
||
{
|
||
startSession();
|
||
if (empty($_SESSION['user_id'])) {
|
||
Response::error('未登录或会话已过期', 401);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 校验当前用户是否拥有某模块权限(同时校验登录态)
|
||
* @param string $module 菜单标识:dashboard/company/person/media/need/marketing/channel/document/preliminary/system/log
|
||
*/
|
||
function checkPermission($module)
|
||
{
|
||
requireLogin();
|
||
$perms = $_SESSION['permissions'] ?? [];
|
||
if (!in_array($module, $perms, true)) {
|
||
Response::error('无权操作', 403);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 校验当前用户是否拥有多个模块权限中的任意一个(同时校验登录态)
|
||
* 用途:功能迁移场景(如文件管理内容迁入竞品资料,document 与 competitor_data 任一权限可访问)
|
||
* @param array $modules 菜单标识数组
|
||
*/
|
||
function checkAnyPermission($modules)
|
||
{
|
||
requireLogin();
|
||
$perms = $_SESSION['permissions'] ?? [];
|
||
foreach ((array)$modules as $m) {
|
||
if (in_array($m, $perms, true)) {
|
||
return;
|
||
}
|
||
}
|
||
Response::error('无权操作', 403);
|
||
}
|
||
|
||
/** 仅超级管理员可操作(如操作日志查询) */
|
||
function requireSuperAdmin()
|
||
{
|
||
requireLogin();
|
||
if (($_SESSION['role_name'] ?? '') !== '超级管理员') {
|
||
Response::error('仅超级管理员可操作', 403);
|
||
}
|
||
}
|
||
|
||
/** 获取客户端 IP */
|
||
function clientIp()
|
||
{
|
||
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
||
}
|
||
|
||
/** 分页参数解析:page / limit */
|
||
function pageParams($defaultLimit = 20)
|
||
{
|
||
$page = max(1, (int)($_REQUEST['page'] ?? 1));
|
||
$limit = min(200, max(1, (int)($_REQUEST['limit'] ?? $defaultLimit)));
|
||
return [$page, $limit];
|
||
}
|