Files
spacestation/agent/admin/hooks/ApiAuthHook.php
T
2025-09-08 14:49:39 +08:00

295 lines
12 KiB
PHP

<?php
class ApiAuthHook
{
// CI instance
private $CI;
// 需要加入钩子函数保护的路由
private $route;
private $pingan_route;
private $auth;//验证身份,不需要验访问权限
private $route_un;//不需要验证token
const H5_API = 'auto';
public function __construct()
{
$this->CI = &get_instance();
// 保护路由为 /api/* 或者 /Api/*
$this->route = '/^api/i';
$this->pingan_route = '/^pingan/i';
$this->auth = ',api/auth';
$this->auth_pingan = ',pingan/auth';
$this->route_un = [
'api/captcha', 'api/login', 'api/login/code', 'api/login/forget', 'api/upload',
'api/common/*', 'pingan/login/*', 'pingan/captcha', 'pingan/register', 'pingan/upload',
'pingan/common/*'
];
//h5白名单
$this->route_un_auto = [
'auto/config/*', 'auto/login/*', 'auto/area/*',
'auto/car/brand', 'auto/car/product/list',
'auto/car/coupon/bizs',
];
}
/**
* 钩子主函数
*/
public function index()
{
// $route 正则匹配是否符合 /api/* 或者 /Api/*
$uri_string = uri_string();
$urlArray = explode("/", $uri_string);
if ($urlArray[0] == 'auto') { //h5
if (!in_array($uri_string, $this->route_un_auto) &&
!in_array($urlArray[0] . '/' . $urlArray[1] . '/*', $this->route_un_auto) &&
!in_array($urlArray[0] . '/' . $urlArray[1] . '/' . $urlArray[2] . '/*', $this->route_un_auto)) {
$headers = $this->CI->input->request_headers();
if ($this->tokenIsExist($headers)) {
$req = $this->validateToken($headers['Authorization'], 'jwt_key_auto');
$this->CI->userId = $req[0];
$this->CI->orgId = $req[1];
if (!$this->CI->userId) {
$this->return_json('登录已过期,请重新登录', 403);
}
} else {
$this->return_json('请先登录', 403);
}
}
} else { //后台
if (preg_match($this->route, $uri_string) || preg_match($this->pingan_route, $uri_string)) {
if (!in_array($uri_string, $this->route_un) &&
!in_array($urlArray[0] . '/' . $urlArray[1] . '/*', $this->route_un)) {
$headers = $this->CI->input->request_headers();
if ($this->tokenIsExist($headers)) {
if ($urlArray[0] == 'pingan') {
$userId = $this->validateToken($headers['Authorization'], 'jwt_key_pingan');
$this->set_session_pingan($userId);
} else {
$userId = $this->validateToken($headers['Authorization']);
$this->set_session($userId);
}
} else {
$this->httpBadResponse(
'The request lacks the authorization token'
);
}
}
}
}
}
private function set_session($userId)
{
$_SESSION['userId'] = intval($userId);
$this->CI->load->model('agent/admin/Market_sys_admin_model');
$re_admin = $this->CI->Market_sys_admin_model->get(['userId' => $userId, 'status' => 0]);
if ($re_admin) {
$_SESSION = $re_admin;
}
$route = uri_string();
if (strstr(',' . $route, $this->auth)) {
return;
}
$request = $this->CI->input->method();
$authorityAry = explode('/', $route); //api/system/user/
$authority_set = '';
if ($request == 'post') {
$authority_set = 'save';
} else if ($request == 'put') {
$authority_set = 'update';
} else if ($request == 'delete') {
$authority_set = 'remove';
} else if (strstr($route, '/page')) {//列表搜索权限
$authority_set = 'list';
}
$menuIds = '';
if ($re_admin['roleId']) {//查找角色
$this->CI->load->model('agent/admin/Market_sys_role_model');
$re_role = $this->CI->Market_sys_role_model->get(['roleId' => $re_admin['roleId'], 'status' => 0]);
if ($re_role) {
$_SESSION['roleCode'] = $re_role['roleCode'];//角色标识
$menuIds = $re_role['menuIds'];
if ($re_role['roleCode'] == 'brand') {//品牌角色
$_SESSION['brandName'] = $re_role['roleName'];
}
}
}
if ($authority_set) {
$show = true;
$authority = $authorityAry[1] . ':' . $authorityAry[2] . ':' . $authority_set;//system:user:save
if ($menuIds) {
if (strstr($route, '/roleMenu')) {//角色分配权限
$authority = 'system:role:' . $authority_set;
} else if (strstr($route, '/dictionaryData')) {//字典项权限
$authority = 'system:dictionary:' . $authority_set;
} else if (strstr($route, '/institution/organizationUser')) {//机构用户权限
$authority = 'institution:organization:' . $authority_set;
} else if (strstr($route, '/institution/teamUser')) {//团队用户权限
$authority = 'institution:team:' . $authority_set;
} else if (strstr($route, '/sylive/groupsUser')) {//分组用户权限
$authority = 'sylive:groups:' . $authority_set;
}
$this->CI->load->model('agent/admin/Market_sys_menu_model');
$re_menu = $this->CI->Market_sys_menu_model->get(["menuId in({$menuIds})" => null, 'status' => 0
, 'authority' => $authority]);
if ($re_menu) {
$show = false;
if ($re_menu['title'] == '登录日志' || $re_menu['title'] == '操作日志') {
} else {
$_SESSION['operation_description'] = $re_menu['title'];//操作功能
$re_menu2 = $this->CI->Market_sys_menu_model->get(["menuId" => $re_menu['parentId'], 'status' => 0]);
$_SESSION['operation_module'] = $re_menu2['title'] ? $re_menu2['title'] : $re_menu['title'];//操作模块
}
}
}
$show && $this->return_json('没有访问权限', 403);
}
}
private function set_session_pingan($userId)
{
$_SESSION['userId'] = intval($userId);
$this->CI->load->model('agent/pingan/Pingan_users_model');
$re_admin = $this->CI->Pingan_users_model->get(['id' => $userId, 'status' => 1]);
if ($re_admin) {
$_SESSION = $re_admin;
}
$route = uri_string();
if (strstr(',' . $route, $this->auth_pingan)) {
return;
}
$request = $this->CI->input->method();
$authorityAry = explode('/', $route); //api/system/user/
$authority_set = '';
if ($request == 'post') {
$authority_set = 'save';
} else if ($request == 'put') {
$authority_set = 'update';
} else if ($request == 'delete') {
$authority_set = 'remove';
} else if (strstr($route, '/page')) {//列表搜索权限
$authority_set = 'list';
}
$menuIds = '';
if ($re_admin['roleId']) {//查找角色
$this->CI->load->model('agent/pingan/Pingan_sys_role_model');
$re_role = $this->CI->Pingan_sys_role_model->get(['roleId' => $re_admin['roleId'], 'status' => 0]);
if ($re_role) {
$_SESSION['roleCode'] = $re_role['roleCode'];//角色标识
$menuIds = $re_role['menuIds'];
if ($re_role['roleCode'] == 'brand') {//品牌角色
$_SESSION['brandName'] = $re_role['roleName'];
}
}
}
if ($authority_set) {
$show = true;
$authority = $authorityAry[1] . ':' . $authorityAry[2] . ':' . $authority_set;//system:user:save
if ($menuIds) {
if (strstr($route, '/roleMenu')) {//角色分配权限
$authority = 'system:role:' . $authority_set;
} else if (strstr($route, '/dictionaryData')) {//字典项权限
$authority = 'system:dictionary:' . $authority_set;
} else if (strstr($route, '/institution/organizationUser')) {//机构用户权限
$authority = 'institution:organization:' . $authority_set;
} else if (strstr($route, '/institution/teamUser')) {//团队用户权限
$authority = 'institution:team:' . $authority_set;
} else if (strstr($route, '/sylive/groupsUser')) {//分组用户权限
$authority = 'sylive:groups:' . $authority_set;
}
$this->CI->load->model('agent/pingan/Pingan_sys_menu_model');
$re_menu = $this->CI->Pingan_sys_menu_model->get(["menuId in({$menuIds})" => null, 'status' => 0
, 'authority' => $authority]);
if ($re_menu) {
$show = false;
if ($re_menu['title'] == '登录日志' || $re_menu['title'] == '操作日志') {
} else {
$_SESSION['operation_description'] = $re_menu['title'];//操作功能
$re_menu2 = $this->CI->Pingan_sys_menu_model->get(["menuId" => $re_menu['parentId'], 'status' => 0]);
$_SESSION['operation_module'] = $re_menu2['title'] ? $re_menu2['title'] : $re_menu['title'];//操作模块
}
}
}
$show && $this->return_json('没有访问权限', 403);
}
}
public function return_json($message = '', $code = 1)
{
header('Content-Type:application/json; charset=utf-8');
echo json_encode(['code' => $code, 'message' => $message], JSON_UNESCAPED_UNICODE);
exit();
}
/**
* 判断 headers 中是否含有 Authorization 字段
*
* @param type $headers
* @return bool|type
*/
public function tokenIsExist($headers = array())
{
return (
array_key_exists('Authorization', $headers) &&
!empty($headers['Authorization'])
);
}
/**
* Authorization 中是否有 json web token 值
*
* @param type $headers
* @return type
*/
public function jwtIsExist($headers)
{
list($jwt) = sscanf($headers['Authorization'], 'market.com %s');
return $jwt;
}
/**
* 校验 json web token 的合法性
*
* @param type $jwt
* @return object
*/
public function validateToken($jwt, $item = 'jwt_key')
{
if ($jwt) {
try {
$token = Authorization::validateToken($jwt, $item);
return $token;
} catch (Exception $ex) {
$this->httpUnauthorizedResponse($ex->getMessage());
}
} else {
$this->httpBadResponse(
'the token is unauthorized'
);
}
}
/**
* http code 400 response
*
* @param type $msg
*/
public function httpBadResponse($msg = NULL)
{
set_status_header(400, $msg);
exit(1);
}
/**
* http code 401 response
*
* @param type $msg
*/
public function httpUnauthorizedResponse($msg = NULL)
{
set_status_header(401, $msg);
exit(1);
}
}