5 关注者

控制器

在创建资源类并指定资源数据应如何格式化之后,接下来要做的就是创建控制器操作,以便通过 RESTful API 将资源公开给最终用户。

Yii 提供了两个基本的控制器类来简化创建 RESTful 操作的工作:yii\rest\Controlleryii\rest\ActiveController。这两个控制器之间的区别在于,后者提供了一组默认的操作,这些操作专门用于处理表示为 活动记录 的资源。因此,如果您正在使用 活动记录 并且对提供的内置操作感到满意,您可以考虑从 yii\rest\ActiveController 扩展您的控制器类,这将允许您使用最少的代码创建强大的 RESTful API。

两者 yii\rest\Controlleryii\rest\ActiveController 提供以下功能,其中一些将在接下来的几节中详细描述

yii\rest\ActiveController 此外还提供以下功能

  • 一组常用的操作:indexviewcreateupdatedeleteoptions
  • 关于请求的操作和资源的用户授权。

创建控制器类

在创建新的控制器类时,命名控制器类的一个约定是使用资源的类型名称并使用单数形式。例如,要提供用户信息,控制器可以命名为 UserController

创建新的操作类似于为 Web 应用程序创建操作。唯一的区别是,对于 RESTful 操作,您不是通过调用 render() 方法使用视图呈现结果,而是直接返回数据。 序列化器响应对象 将处理从原始数据到请求格式的转换。例如,

public function actionView($id)
{
    return User::findOne($id);
}

过滤器

yii\rest\Controller 提供的大多数 RESTful API 功能都是根据 过滤器 实现的。特别是,以下过滤器将按列出的顺序执行

这些命名过滤器在behaviors()方法中声明。您可以重写此方法来配置单个过滤器、禁用其中一些过滤器或添加您自己的过滤器。例如,如果您只想使用HTTP基本身份验证,您可以编写以下代码

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['authenticator'] = [
        'class' => HttpBasicAuth::class,
    ];
    return $behaviors;
}

CORS

跨源资源共享过滤器添加到控制器比添加上面描述的其他过滤器稍微复杂一些,因为CORS过滤器必须在身份验证方法之前应用,因此与其他过滤器相比,需要稍微不同的方法。此外,必须为CORS预检请求禁用身份验证,以便浏览器可以安全地确定是否可以预先发出请求,而无需发送身份验证凭据。以下显示了将yii\filters\Cors过滤器添加到从yii\rest\ActiveController扩展的现有控制器的代码

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    $behaviors = parent::behaviors();

    // remove authentication filter
    $auth = $behaviors['authenticator'];
    unset($behaviors['authenticator']);
    
    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::class,
    ];
    
    // re-add authentication filter
    $behaviors['authenticator'] = $auth;
    // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
    $behaviors['authenticator']['except'] = ['options'];

    return $behaviors;
}

扩展ActiveController

如果您的控制器类从yii\rest\ActiveController扩展,则应将其modelClass属性设置为要通过此控制器提供服务的资源类的名称。该类必须从yii\db\ActiveRecord扩展。

自定义操作

默认情况下,yii\rest\ActiveController提供以下操作

  • index:逐页列出资源;
  • view:返回指定资源的详细信息;
  • create:创建新的资源;
  • update:更新现有资源;
  • delete:删除指定资源;
  • options:返回支持的HTTP方法。

所有这些操作都是通过actions()方法声明的。您可以通过重写actions()方法来配置这些操作或禁用其中一些操作,如下所示,

public function actions()
{
    $actions = parent::actions();

    // disable the "delete" and "create" actions
    unset($actions['delete'], $actions['create']);

    // customize the data provider preparation with the "prepareDataProvider()" method
    $actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];

    return $actions;
}

public function prepareDataProvider()
{
    // prepare and return a data provider for the "index" action
}

请参阅各个操作类的类参考,以了解可用的配置选项。

执行访问检查

当通过RESTful API公开资源时,您通常需要检查当前用户是否具有访问和操作请求资源的权限。使用yii\rest\ActiveController,可以通过重写checkAccess()方法来实现,如下所示,

/**
 * Checks the privilege of the current user.
 *
 * This method should be overridden to check whether the current user has the privilege
 * to run the specified action against the specified data model.
 * If the user does not have access, a [[ForbiddenHttpException]] should be thrown.
 *
 * @param string $action the ID of the action to be executed
 * @param \yii\base\Model $model the model to be accessed. If `null`, it means no specific model is being accessed.
 * @param array $params additional parameters
 * @throws ForbiddenHttpException if the user does not have access
 */
public function checkAccess($action, $model = null, $params = [])
{
    // check if the user can access $action and $model
    // throw ForbiddenHttpException if access should be denied
    if ($action === 'update' || $action === 'delete') {
        if ($model->author_id !== \Yii::$app->user->id)
            throw new \yii\web\ForbiddenHttpException(sprintf('You can only %s articles that you\'ve created.', $action));
    }
}

checkAccess()方法将由yii\rest\ActiveController的默认操作调用。如果您创建新的操作并且也希望执行访问检查,则应在新的操作中显式调用此方法。

提示:您可以使用基于角色的访问控制 (RBAC) 组件来实现checkAccess()

发现错别字或您认为此页面需要改进?
在github上编辑它 !