【问题标题】:Yii2 REST Simplify BasicAuthYii2 REST 简化 BasicAuth
【发布时间】:2015-04-12 03:13:47
【问题描述】:

我对在 Yii2 中创建 REST api 的简单程度印象深刻。但是,我在理解基本身份验证时遇到了一些麻烦。我的需求非常简单,我希望我的解决方案也能效仿。

我在这里需要基本令牌认证。我现在什至不反对对其进行硬编码,但这是我迄今为止所做的。

我有一个数据库表来保存我的单数令牌 ApiAccess(id, access_token)

ApiAccess.php - 模型 - 注意:IDE 在第一行显示语法错误

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

Module.php - 在 init() 函数中

 \Yii::$app->user->enableSession = false;

我制作了一个 ApiController,每个后续名词都可以扩展

ApiController.php

 use yii\rest\ActiveController;
 use yii\filters\auth\HttpBasicAuth;
 use app\models\db\ApiAccess;

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

就目前而言,在浏览器中访问 api 端点会提示输入用户名和密码。通过 REST 客户端请求显示访问错误。

如何正确地将 HttpBasicAuth 绑定到我的 ApiAccess 模型?

如何硬编码 api 访问令牌?(显然第一个选项是最好的)

【问题讨论】:

    标签: php api rest yii yii2


    【解决方案1】:

    让我们观察并尝试了解 REST 的“yii”方式基本身份验证。

    第一。当您向 REST 控制器添加行为时,您启用了基本身份验证:

    $behaviors['authenticator'] = [
        'class' => HttpBasicAuth::className(),
      ];
    

    正如你所做的那样。这是什么意思?这意味着您的应用程序将解析您的授权标头。它看起来像:

    Authorization : Basic base64(user:password)
    

    这是 yii2 的一个技巧。如果你仔细看代码,你会发现 yii 使用了来自用户字段的access_token,所以你的标题应该是这样的:

    Authorization : Basic base64(access_token:)
    

    如果你想改变这个行为,你可以自己解析这个头:

    $behaviors['authenticator'] = [
                'class' => HttpBasicAuth::className(),
                'auth' => [$this, 'auth']
            ];
    ....
    public function auth($username, $password)
        {
            return \app\models\User::findOne(['login' => $username, 'password' => $password]);
        }
    

    要做的第二件事。您必须从 identityInterface 实现 findIdentityByAccessToken() 函数。 为什么你的 IDE 抱怨?

    class User extends ActiveRecord implements IdentityInterface
    

    这是您的用户类声明的外观。

    从你的实现和结构来看:

    public static function findIdentityByAccessToken($token, $type = null)
       {
         return static::findOne(['access_token' => $token]);
       }
    

    你没有返回实现标识接口的类的对象。

    如何正确制作? 将列 access_token 添加到您的用户表中,并返回您的用户模型(您可以在此处查看它的外观 - https://github.com/yiisoft/yii2-app-advanced/blob/master/common/models/User.php) 如果您这样做 - 默认代码将适用于您的 findIdentityByAccessToken() 实现。

    如果您不想在 users 表中添加字段 - 使用 user_id,access_token 字段创建一个新字段。那么你的实现应该如下所示:

    public static function findIdentityByAccessToken($token, $type = null)
       {
         $apiUser = ApiAccess::find()
            ->where(['access_token' => $token])
            ->one();
         return static::findOne(['id' => $apiUser->user_id, 'status' => self::STATUS_ACTIVE]);
       }
    

    希望我能回答你所有的问题。

    【讨论】:

    • 我有这个工作,看看它现在应该如何工作。谢谢你。我仍然有一个与覆盖仅针对此模块的 LDAP 身份验证有关的问题。如果我不能自己解决,我会发布一个单独的问题。
    • findOne 不加密密码以查看它是否与 password_hash 匹配 - 如何将 validatePassword 与 findOne 合并?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 2016-06-04
    相关资源
    最近更新 更多