6 关注者

身份验证

与 Web 应用程序不同,RESTful API 通常是无状态的,这意味着不应该使用会话或 Cookie。因此,每个请求都应该包含某种身份验证凭据,因为用户的身份验证状态可能无法通过会话或 Cookie 保持。一个常见的做法是,在每个请求中发送一个秘密访问令牌来验证用户。由于访问令牌可用于唯一识别和验证用户,API 请求应始终通过 HTTPS 发送以防止中间人(MitM)攻击

发送访问令牌有不同的方法

  • HTTP 基本身份验证:访问令牌作为用户名发送。这只能在访问令牌可以在 API 消费者端安全存储时使用。例如,API 消费者是运行在服务器上的程序。
  • 查询参数:访问令牌作为 API URL 中的查询参数发送,例如,https://example.com/users?access-token=xxxxxxxx。由于大多数 Web 服务器会将查询参数保存在服务器日志中,因此这种方法主要用于提供JSONP请求,这些请求无法使用 HTTP 标头发送访问令牌。
  • OAuth 2:访问令牌由消费者从授权服务器获取,并根据 OAuth2 协议通过HTTP 承载令牌发送到 API 服务器。

Yii 支持所有上述身份验证方法。您也可以轻松创建新的身份验证方法。

要为您的 API 启用身份验证,请执行以下步骤

  1. 配置user应用程序组件
    • enableSession属性设置为false
    • loginUrl属性设置为null以显示 HTTP 403 错误而不是重定向到登录页面。
  2. 通过在您的 REST 控制器类中配置authenticator行为来指定您计划使用哪些身份验证方法。
  3. 在您的用户身份类中实现yii\web\IdentityInterface::findIdentityByAccessToken()

步骤 1 不是必需的,但对于应该无状态的 RESTful API 是推荐的。当enableSessionfalse时,用户的身份验证状态将不会使用会话在请求之间持久化。相反,每个请求都会执行身份验证,这可以通过步骤 2 和 3 完成。

提示:如果您正在根据应用程序开发 RESTful API,您可以在应用程序配置中配置user应用程序组件的enableSession。如果您将 RESTful API 作为模块开发,您可以在模块的init()方法中添加以下代码行,如下所示

public function init()
{
    parent::init();
    \Yii::$app->user->enableSession = false;
}

例如,要使用 HTTP 基本身份验证,您可以按如下方式配置authenticator行为:

use yii\filters\auth\HttpBasicAuth;

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

如果要支持上面解释的所有三种身份验证方法,可以使用CompositeAuth,如下所示:

use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;

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

authMethods中的每个元素都应该是身份验证方法类名或配置数组。

findIdentityByAccessToken() 的实现是应用程序特定的。例如,在简单的场景中,每个用户只能拥有一个访问令牌,您可以在用户表中的 access_token 列中存储访问令牌。然后可以在 User 类中轻松实现该方法,如下所示:

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }
}

在启用上述认证后,对于每个 API 请求,请求的控制器将在其 beforeAction() 步骤中尝试认证用户。

如果认证成功,控制器将执行其他检查(例如速率限制、授权),然后执行操作。可以使用 Yii::$app->user->identity 获取认证后的用户身份信息。

如果认证失败,将返回一个 HTTP 状态码为 401 的响应,以及其他合适的标头(例如,用于 HTTP 基本身份验证的 WWW-Authenticate 标头)。

授权

用户认证后,您可能想要检查他/她是否具有对请求资源执行请求操作的权限。此过程称为授权,将在 授权部分 中详细介绍。

如果您的控制器继承自 yii\rest\ActiveController,您可以重写 checkAccess() 方法以执行授权检查。该方法将由 yii\rest\ActiveController 提供的内置操作调用。

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