Yii2认证授权源码解读

在现在的开发中,大多数的应用是采用前后端分离的方式进行开发的,这样可以灵活的适应多种客户端。但是,问题也来了,安全在这个时候就很重要了。当然,yii已经给我们提供了现成的认证授权,使用起来很方便。但是,有时候也不是完全能够满足我们的实际需求,这个时候就需要我们自己来重写来修改了。前提是,我们要对这个框架有足够的了解。

 好了,废话不多说,带你一起来解读下,先来了解了解认证授权模块的代码结构(如下图所示),先来说说图中红色箭头指出的三者之前的关系,基础的权限抽象类(AuthMethod.php)继承了定义权限功能接口(AuthInetrface.php)和动作过滤器类(ActionFilter):

(1)定义权限功能接口(AuthInetrface.php),里面定义了三个功能。分别是:

        1、用户认证;

        2、挑战(这个得特别说明一下,用基础认证来方式来说吧,客户端请求一个接口,然后服务端接收到请求后,会检查请求发送来的数据中是否包含有: “Authorization: Basic YWRtaW46YWRtaW4=”这种格式的数据,若无,则服务端会发送HTTP信息头“WWW-Authenticate: Basic realm=“.api””,这个时候浏览器会弹出一个要求你输入用户名密码的弹出框,输入完用户名密码点击发送至服务端,这个时候服务端会解析用户名密码,若合法,则会返回你想要请求的信息。反之,会继续弹框,让你输入用户名密码);

       3、处理异常(直接抛出一个401 无权限提示)。

(2)权限方法类(AuthMethod.php)

      这个类里面主要重写了动作执行前过滤。下图中有个方法需要特别注意下:

    

上图箭头指出的方法,主要实现了用户认证功能,该里面有一个重要的方法实现,用基础权限认证来举个例子。

看下面红色方框中的方法,用木有很熟悉,对,他就是你用自己的方式认证用户重写的方法,记得在认证组件中配置奥。

(3)上面说了那么多,下面来说说怎样修改成满足你自己需求的过滤器。

<?php

namespace app\behaviors;

use Yii;
use yii\base\InvalidConfigException;
use yii\filters\auth\AuthInterface;
use yii\filters\auth\AuthMethod;
use yii\helpers\StringHelper;
use yii\web\ForbiddenHttpException;
use yii\web\UnauthorizedHttpException;

/**
 * 权限校验
 * Class CheckPermission
 * @package app\behaviors
 */
class CompositeAuth extends AuthMethod
{
    public $authMethods = [];

    /**
     * @var array 权限排除列表,排除exclude中的权限,不去做权限验证
     */
    public $exclude = [];

    public function beforeAction($action) : bool
    {
        if (empty($this->authMethods)) {
            return true;
        }

        $response = $this->response ?: Yii::$app->getResponse();

        try {
            $identity = $this->authenticate(
                $this->user ?: Yii::$app->getUser(),
                $this->request ?: Yii::$app->getRequest(),
                $response
            );

            //用户必须要求登录,且已登录,且需要做权限验证
            if ($identity !== null && !$this->isExclude($action)) {
                $rights   = $identity->normal_right ?? [];
                $uniqueId = $action->getUniqueId();
                if (null !== $identity && !isset($rights[$uniqueId])) {
                    throw new ForbiddenHttpException('您当前请求没有权限,请联系管理员');
                }
            }
        } catch (UnauthorizedHttpException $e) {
            if ($this->isOptional($action)) {
                return true;
            }

            throw $e;
        }

        if ($identity !== null || $this->isOptional($action)) {
            return true;
        }

        $this->challenge($response);
        $this->handleFailure($response);

        return false;
    }


    /**
     * {@inheritdoc}
     */
    public function authenticate($user, $request, $response)
    {
        foreach ($this->authMethods as $i => $auth) {
            if (!$auth instanceof AuthInterface) {
                $this->authMethods[$i] = $auth = Yii::createObject($auth);
                if (!$auth instanceof AuthInterface) {
                    throw new InvalidConfigException(get_class($auth) . ' must implement yii\filters\auth\AuthInterface');
                }
            }

            $identity = $auth->authenticate($user, $request, $response);
            if ($identity !== null) {
                return $identity;
            }
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function challenge($response)
    {
        foreach ($this->authMethods as $method) {
            /* @var $method AuthInterface */
            $method->challenge($response);
        }
    }

    protected function isExclude($action)
    {
        $id = $this->getActionId($action);
        foreach ($this->exclude as $pattern) {
            if (StringHelper::matchWildcard($pattern, $id)) {
                return true;
            }
        }

        return false;
    }
}

(4)配置你自定义的、满足你需求的认证授权方式。

<?php
namespace app\controllers;

use yii\rest\ActiveController;
use Yii;
use yii\behaviors\CompositeAuth;   //重写认证授权实现方式
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;

class ArticleController extends ActiveController
{
    
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        $behaviors['authenticator'] = [
            'class' => CompositeAuth::class,
            'authMethods' => [
                HttpBasicAuth::class,
                HttpBearerAuth::class,
            ],
            'optional' => [  //optional,框架已定义的不需要授权的路由数组
                'index',
            ],
            'except' => [      //except  自定义参数,认证但无需授权的路由数组
                'about-create' 
            ],
        ];
        return $behaviors;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值