【fastadmin】踩坑第一发-前台会员中心权限控制

xiaopang996 1月前 359

正在做前台会员中心发现后台设置了规则以后毫无乱用
然后在社区中搜索
image.png
看到了这个
然后根据文档中
image.png
找到了这三个基类
首先看application/common/controller/Frontend.php //前台基类控制器
我们来分析构造函数

    public function _initialize()
    {
        //移除HTML标签
        $this->request->filter('strip_tags');
        $modulename = $this->request->module();
        $controllername = strtolower($this->request->controller());
        $actionname = strtolower($this->request->action());

        // 如果有使用模板布局
        if ($this->layout) {
            $this->view->engine->layout('layout/' . $this->layout);
        }
        $this->auth = Auth::instance();

        // token
        $token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));

        $path = str_replace('.', '/', $controllername) . '/' . $actionname;
        // 设置当前请求的URI
        $this->auth->setRequestUri($path);
        // 检测是否需要验证登录
        if (!$this->auth->match($this->noNeedLogin)) {
            //初始化
            $this->auth->init($token);
            //检测是否登录
            if (!$this->auth->isLogin()) {
                $this->error(__('Please login first'), 'user/login');
            }
            // 判断是否需要验证权限
            if (!$this->auth->match($this->noNeedRight)) {
                // 判断控制器和方法判断是否有对应权限
                if (!$this->auth->check($path)) {
                    $this->error(__('You have no permission'));
                }
            }
        } else {
            // 如果有传递token才验证是否登录状态
            if ($token) {
                $this->auth->init($token);
            }
        }

        $this->view->assign('user', $this->auth->getUser());

        // 语言检测
        $lang = strip_tags($this->request->langset());

        $site = Config::get("site");

        $upload = \app\common\model\Config::upload();

        // 上传信息配置后
        Hook::listen("upload_config_init", $upload);

        // 配置信息
        $config = [
            'site'           => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
            'upload'         => $upload,
            'modulename'     => $modulename,
            'controllername' => $controllername,
            'actionname'     => $actionname,
            'jsname'         => 'frontend/' . str_replace('.', '/', $controllername),
            'moduleurl'      => rtrim(url("/{$modulename}", '', false), '/'),
            'language'       => $lang
        ];
        $config = array_merge($config, Config::get("view_replace_str"));

        Config::set('upload', array_merge(Config::get('upload'), $upload));

        // 配置信息后
        Hook::listen("config_init", $config);
        // 加载当前控制器语言包
        $this->loadlang($controllername);
        $this->assign('site', $site);
        $this->assign('config', $config);
    }

权限判断在这段

        if (!$this->auth->match($this->noNeedLogin)) {
            //初始化
            $this->auth->init($token);
            //检测是否登录
            if (!$this->auth->isLogin()) {
                $this->error(__('Please login first'), 'user/login');
            }
            // 判断是否需要验证权限
            if (!$this->auth->match($this->noNeedRight)) {
                // 判断控制器和方法判断是否有对应权限
                if (!$this->auth->check($path)) {
                    $this->error(__('You have no permission'));
                }
            }
        } else {
            // 如果有传递token才验证是否登录状态
            if ($token) {
                $this->auth->init($token);
            }
        }

我们在用的过程中可以知道 登陆和不登陆的状态权限判断没问题 那么问题就出现在 // 判断是否需要验证权限这一个判断中

noNeedRight 无需鉴权的方法,但需要登录 那么他就只需要登陆 无需验证权限
我们打断点可以得知 不管后台如何设置会员规则 都不会进入这个验证权限的判断中
继续跟踪函数 找到auth->match
    /**
     * 检测当前控制器和方法是否匹配传递的数组
     *
     * @param array $arr 需要验证权限的数组
     * @return boolean
     */
    public 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;
    }

image.png
我们可以看到我们在控制器中定义的是* 这样在match会直接返回false
然后返回来看构造函数中的if 是! 这样的话只有为match返回true的时候才会去判断权限
所以我们只需修改一下构造函数中的

            // 判断是否需要验证权限
            if (!$this->auth->match($this->noNeedRight)) {

修改为

            // 判断是否需要验证权限
            if ($this->auth->match($this->noNeedRight)) {

我们来看看效果
image.png
去掉个人资料的权限
image.png
我们再加上权限
image.png
image.png
同理 api权限控制与这个相同 去掉那个判断中的!

最后于 1月前 被xiaopang996编辑 (刚刚写的有问题 重新更正一下)
最佳回复
  • xiaopang996 1月前

    刚刚脑子秀逗了 没转过弯 再次更新一下 上面那样修改 会导致设置noNeedRight不起作用
    其实只需要修改applicationindexcontrollerUser.php

     protected $noNeedRight = ['index'];

    这个的意思是 不需要权限控制 但是需要登陆的 你把控制器里面不需要控制权限但是需要登陆的方法写进去

    protected $noNeedLogin = ['login', 'register', 'third'];

    这个是不需要登陆的方法
    这样修改*就行了,写进去不需要权限控制的 但是需要登陆的 那么剩余的方法就是 需要登陆 并且还需要判断权限的
    image.png
    效果相同
    image.png
    image.png
    image.png
    image.png

最新回复 (6)
  • xiaopang996 楼主 最佳回复 1月前
    感谢TA
    0 引用 2

    刚刚脑子秀逗了 没转过弯 再次更新一下 上面那样修改 会导致设置noNeedRight不起作用
    其实只需要修改applicationindexcontrollerUser.php

     protected $noNeedRight = ['index'];

    这个的意思是 不需要权限控制 但是需要登陆的 你把控制器里面不需要控制权限但是需要登陆的方法写进去

    protected $noNeedLogin = ['login', 'register', 'third'];

    这个是不需要登陆的方法
    这样修改*就行了,写进去不需要权限控制的 但是需要登陆的 那么剩余的方法就是 需要登陆 并且还需要判断权限的
    image.png
    效果相同
    image.png
    image.png
    image.png
    image.png

    最后于 1月前 被xiaopang996编辑
  • xiaopang996 楼主 1月前
    感谢TA
    0 引用 3

    @胡导 重新看一下 刚刚那个有问题

  • miajeay 1月前
    感谢TA
    0 引用 4

    记一下

  • 小天天 9天前
    感谢TA
    0 引用 5

    有用!

  • llt1986 6天前
    感谢TA
    0 引用 6

    刚发现这个问题,不错!

  • 灰化肥 1天前
    感谢TA
    0 引用 7

  • 未登录
    8
返回