由于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);
    }
}