Слияние кода завершено, страница обновится автоматически
<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2021-04-27 12:55:00
// +----------------------------------------------------------------------
namespace buwang\base;
use app\manage\model\Token;
use buwang\exception\AuthException;
use buwang\service\AuthService;
use think\facade\Config;
use think\facade\View;
/**
* 控制器基础类
*/
abstract class PluginBaseController extends Manage
{
//无需登录的方法,同时也就不需要鉴权了
protected $noNeedLogin = ['*'];
//无需鉴权的方法,但需要登录
protected $noNeedRight = ['*'];
//权限控制类
protected $auth_service = null;
// 插件名
protected $addon = '';
//插件路径
protected $controller = null;
//插件执行方法
protected $action = null;
// 插件路径
protected $addon_path;
// 视图模型实例
protected $view;
// 插件配置
private $addon_config;
// 插件信息
private $addon_info;
//布局模板 可用相对地址 如 ../../../view/public/layout
protected $layout = 'layout';
public function __construct()
{
if(!$this->app) $this->app = app();
if(!$this->request) $this->request = $this->app->request;
//移除HTML标签
$this->request->filter('trim');
// 是否自动转换控制器和操作名
$convert = Config::get('url_convert');
$filter = $convert ? 'strtolower' : 'trim';
// 处理路由参数
//$var = $this->>app->request->rule()->getVars();
$var = $this->request->param(['addon', 'controller', 'action']);
$addon = isset($var['addon']) ? $var['addon'] : '';
$controller = isset($var['controller']) ? $var['controller'] : '';
$action = isset($var['action']) ? $var['action'] : '';
//当前插件名,方法,控制器
$this->addon = $addon ? call_user_func($filter, $addon) : '';
$this->controller = $controller ? call_user_func($filter, $controller) : 'index';
$this->action = $action ? call_user_func($filter, $action) : 'index';
$this->addon_path = $this->app->addons->getAddonsPath() . $this->addon . DIRECTORY_SEPARATOR;
$this->addon_config = "addon_{$this->addon}_config";
$this->addon_info = "addon_{$this->addon}_info";
//view模板,layout模板布局设置
$this->view = clone VIEW::engine('Think');
$view_data = Config::get('view');
$view_data['tpl_replace_string']['__ADDON__'] = '/static/addons/' . $this->addon . '/';
$this->view->config($view_data);
// 如果有使用模板布局
//$this->layout && $this->>app->view->engine()->layout($this->layout);
//自动加载插件目录下的composer包
if (empty(self::$vendorLoaded[$this->addon])) {
$pluginVendorAutoLoadFile = $this->addon_path .'vendor'.DS.'autoload.php';
if (file_exists($pluginVendorAutoLoadFile)) {
require_once $pluginVendorAutoLoadFile;
}
self::$vendorLoaded[$this->addon] = true;
}
$thisModule = "addons/{$this->addon}";
$thisController = $this->controller;
$thisAction = $this->action;
list($thisControllerArr, $jsPath) = [explode('.', $thisController), null];
foreach ($thisControllerArr as $vo) {
empty($jsPath) ? $jsPath = parse_name($vo) : $jsPath .= '/' . parse_name($vo);
}
$autoloadJs = file_exists(root_path('public') . "static/{$thisModule}/js/{$jsPath}.js") ? true : false;
$thisControllerJsPath = "{$thisModule}/js/{$jsPath}.js";
$data = [
'adminModuleName' => $thisModule,//插件请求基地址
'thisController' => parse_name($thisController),
'thisAction' => $thisAction,
'thisRequest' => parse_name("{$thisModule}/{$thisController}/{$thisAction}"),
'thisControllerJsPath' => "{$thisControllerJsPath}",
'autoloadJs' => $autoloadJs,
'isSuperAdmin' => 0,
'domain' => $this->request->domain(),
'version' => env('app_debug') ? time() : BW_VERSION,
];
$this->assign($data);
$this->pluginAuth();
parent::initialize();
///父类的调用必须放在设置模板路径之后
parent::__construct();
}
//插件必备初始化函数 插件权限节点鉴权
private function pluginAuth()
{
//转化获取当前的路由节点地址
$node = "/addons/{$this->addon}/" . parse_name("{$this->controller}", 1) . "/{$this->action}";
$this->auth_service = AuthService::instance();
//传入当前请求的方法
$this->auth_service->setAction($this->action);
//检测是否登录
$this->scopes = '';
$this->token = get_token($this->request);
$code = 401;
$err_msg = "未登录,请先去登录";
$err_code = 400000;
$this->user = false;
if ($this->token) {
//不需要登录捕获422错误
//获取到token,解析token,捕获token签名不正确,签名尚未生效,签名在某个时间点之后才能用,token已经过期,token解析错误
try{
$jwtinfo = self::decodeToken($this->token);
}catch (\Throwable $e){
$this->token = '';//token解析报错算token失效,当做未登录处理
$jwtinfo = null;
}
if($jwtinfo){
//和redis存储的token进行验证有效性
$this->user = Token::validateRedisToken($this->token, $jwtinfo);
$code = Token::getErrorCode() == 400001 ? 401 : 200;
$err_code = Token::getErrorCode() ?: 400000;
$err_msg = Token::getError("未登录,请先去登录");
}
}
//赋值用户的登录状态
if($this->user) $this->isUserLogin =true;
// 检测是否需要验证登录
if (!$this->auth_service->match($this->noNeedLogin)) {
if (!$this->token || !$this->user) throw new AuthException($err_msg,401);
// 判断是否需要验证权限
if (!$this->auth_service->match($this->noNeedRight)) {
// 判断控制器和方法判断是否有对应权限
//目前只鉴权scopes为admin和member的后台相关节点
AuthService::auth($this->user['id'], $this->scopes, $node);
}
}
}
/**
* 加载模板输出
* @param string $template
* @param array $vars 模板文件名
* @return false|mixed|string 模板输出变量
*/
protected function fetch($template = '', $vars = [])
{
return $this->view->fetch($template, $vars);
}
/**
* 渲染内容输出
* @access protected
* @param string $content 模板内容
* @param array $vars 模板输出变量
* @return mixed
*/
protected function display($content = '', $vars = [])
{
return $this->view->display($content, $vars);
}
/**
* 模板变量赋值
* @access protected
* @param mixed $name 要显示的模板变量
* @param mixed $value 变量的值
* @return $this
*/
protected function assign($name, $value = '')
{
if (is_array($name)) {
$this->view->assign($name);
} else {
$this->view->assign([$name => $value]);
}
return $this;
}
/**
* 初始化模板引擎
* @access protected
* @param array|string $engine 引擎参数
* @return $this
*/
protected function engine($engine)
{
$this->view->engine($engine);
return $this;
}
/**
* 插件基础信息
* @return array
*/
final public function getInfo()
{
$info = Config::get($this->addon_info, []);
if ($info) {
return $info;
}
// 文件属性
$info = $this->info ?? [];
// 文件配置
$info_file = $this->addon_path . 'info.ini';
if (is_file($info_file)) {
$_info = parse_ini_file($info_file, true, INI_SCANNER_TYPED) ?: [];
$_info['url'] = addons_url();
$info = array_merge($_info, $info);
}
Config::set($info, $this->addon_info);
return isset($info) ? $info : [];
}
/**
* 获取配置信息
* @param bool $type 是否获取完整配置
* @return array|mixed
*/
final public function getConfig($type = false)
{
$config = Config::get($this->addon_config, []);
if ($config) {
return $config;
}
$config_file = $this->addon_path . 'config.php';
if (is_file($config_file)) {
$temp_arr = (array)include $config_file;
if ($type) {
return $temp_arr;
}
foreach ($temp_arr as $key => $value) {
$config[$key] = $value['value'];
}
unset($temp_arr);
}
Config::set($config, $this->addon_config);
return $config;
}
/**
* 获取对象的属性字段及属性值
* @param [type] $property_scope 属性域
* @param boolean $static_excluded 是否排除静态属性
* @return array
* @throws \ReflectionException|\Exception
*/
protected function getProperties($property_scope = null, $static_excluded = false)
{
// 校验反射域是否合法
if (isset($property_scope) && !in_array($property_scope, [
\ReflectionProperty::IS_STATIC,
\ReflectionProperty::IS_PUBLIC,
\ReflectionProperty::IS_PROTECTED,
\ReflectionProperty::IS_PRIVATE,
])) {
throw new \Exception("reflection class property scope illegal!");
}
$properties_mapping = [];
// 谈判官
$classRef = new \ReflectionClass($this);
$properties = isset($property_scope) ? $classRef->getProperties($property_scope) : $classRef->getProperties();
foreach ($properties as $property) {
// 为了兼容反射私有属性
$property->setAccessible(true);
// 当不想获取静态属性时
if ($property->isStatic() && $static_excluded) {
continue;
}
if(in_array($property->getName(),['noNeedLogin', 'noNeedRight'])){
// 将得到的类属性同具体的实例绑定解析,获得实例上的属性值
$properties_mapping[$property->getName()] = $property->getValue($this);
}
}
return $properties_mapping;
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )