由于api接口需要用到管理员(非用户登录鉴权)登录鉴权(中台接口),选择直接使用框架自带的一套登录鉴权功能,但是由于是在接口中使用,需要修改一部分代码。
创建一个用于接口控制器继承的父类文件 Apitools.php
父类Apitools继承Api类
use app\common\controller\Api; class ApiTools extends Api
父类内添加方法名控制权限
//无需登录 protected $noNeedLogin = ['login']; //无需鉴权 protected $noNeedRight = '*';
父类Apitools示例:
namespace app\api\controller;
use app\admin\model\Admin as AdminModel;
use app\common\controller\Api;
use app\common\library\Token;
use app\admin\model\Admin;
use think\Request;
use think\Loader;
use think\Validate;
use fast\Auth;
/**
* 前台api基类
*/
class ApiTools extends Api
{
//无需登录
protected $noNeedLogin = ['login'];
//无需鉴权
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
$this->isLogin();
}
// 登录检查
public function isLogin()
{
if(!$this->match($this->noNeedLogin)){
$token = $this->request->header('Token', '');
$user = Admin::get(['token' => $token]);
$getAdminToken = $this->getAdminToken($token);
if (!$token || !$user || $getAdminToken == 1 || !$getAdminToken) {
$this->success('请重新登录', null, -1);
}
if ($user['status'] === 'hidden') {
$this->success('账号已被禁止登录', null, -1);
}
$this->userId = $user['id'];
$this->auth = new Auth();
// 判断是否无需鉴权的方法
if (!$this->match($this->noNeedRight)) {
// 开始节点验证
$controllerName = Loader::parseName($this->request->controller());
$controllerName = str_replace('wxapp.', '', $controllerName);
$actionName = strtolower($this->request->action());
$this->path = str_replace('.', '/', $controllerName) . '/' . $actionName;
if (!$this->auth->check($this->path, $this->userId)) {
$this->success(__('You have no permission.'));
}
}
}
}
/**
* 检测当前控制器和方法是否匹配传递的数组
*
* @param array $arr 需要验证权限的数组
* @return bool
*/
protected function match($arr = [])
{
$request = Request::instance();
$arr = is_array($arr) ? $arr : explode(',', $arr);
if (!$arr) {
return false;
}
$arr = array_map('strtolower', $arr);
// 是否存在
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
return true;
}
// 没找到匹配
return false;
}
/**
* 检测传递的参数是否存在
* @authorMessiah
* @param $name 数据库需要的参数名
* @param $param 请求来源参数
*/
public function paramDetection($name, $param)
{
$name = array_flip($name);
$res = array_diff_key($name, $param);
if ($res) {
$this->success("缺少参数", array_keys($res), 203);
};
foreach ($param as $k => $v) {
if ($v == '' || $v == null) $this->success("参数错误", $k, 203);
};
}
// 获取token
public function getAdminToken($token = '')
{
if ($token) {
$adminId = AdminModel::where('token', $token)->value('id');
$res = Token::get($token, $adminId);
return $res;
};
return false;
}
}
- Api基类部分修改
位置:application/common/controller/Api.php
初始化函数 _initialize 内修改鉴权部分,屏蔽api模块下的鉴权,改为由父类Apitools进行控制;(根据需求修改)
Api基类修改示例:
// 检测是否需要验证登录
if (!$this->auth->match($this->noNeedLogin)) {
//初始化
$this->auth->init($token);
// 2023.2.27 messiah 修改开始 修改判断请求来源是否是api模块下
$requestPath = $modulename;// . "/" . explode('/',str_replace('.', '/', $controllername))[0];
if($requestPath !== 'api')
{
//检测是否登录
if (!$this->auth->isLogin()) {
$this->error(__('Please login first'), null, 401);
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight)) {
// 判断控制器和方法判断是否有对应权限
if (!$this->auth->check($path)) {
$this->error(__('You have no permission'), null, 403);
}
}
}
// 2023.2.27 messiah 修改结束
// //检测是否登录
// if (!$this->auth->isLogin()) {
// $this->error(__('Please login first'), null, 401);
// }
// // 判断是否需要验证权限
// if (!$this->auth->match($this->noNeedRight)) {
// // 判断控制器和方法判断是否有对应权限
// if (!$this->auth->check($path)) {
// $this->error(__('You have no permission'), null, 403);
// }
// }
} else {
// 如果有传递token才验证是否登录状态
if ($token) {
$this->auth->init($token);
}
}