【问题标题】:Yii2-Api: How to pass Token for the HttpBearer FilterYii2-Api:如何为 HttpBearer 过滤器传递 Token
【发布时间】:2018-05-11 21:05:34
【问题描述】:

这是我的控制器

class ClientController extends ActiveController
{
    public $modelClass = 'common\models\Client'; 
    public $serializer = [
      'class' => 'yii\rest\Serializer',
      'collectionEnvelope' => 'items',
  ];
    public function behaviors()
    {

        return ArrayHelper::meenter code hererge(parent::behaviors(),[
          [
            'class' => \yii\filters\Cors::className(),
        ],
           [
           'class' => CompositeAuth::className(),
           'except' => ['options'],
           'authMethods' => [
           HttpBearerAuth::className(),
             QueryParamAuth::className(),

           ],
        ],

           [
           'class' => TimestampBehavior::className(),
           ],
             [
              'class' => 'yii\filters\ContentNegotiator',
              'only' => ['view', 'index'],  // in a controller
              // if in a module, use the following IDs for user actions
              // 'only' => ['user/view', 'user/index']
              'formats' => [
                  'application/json' => Response::FORMAT_JSON,
              ],

          ],
           [
           'class' => AccessControl::className(),
    // We will override the default rule config with the new AccessRule class
           'ruleConfig' => [
           'class' => AccessRule::className(),
           ],
           'only' => ['create', 'delete'],
           'rules' => [[
           'actions' => ['create'],
           'allow' => true,
            // Allow users, moderators and admins to create
           'roles' => [
           User::ROLE_ADMIN
           ],
        ],

           [
           'actions' => ['delete'],
           'allow' => true,
            // Allow admins to delete
           'roles' => [
           User::ROLE_ADMIN
           ],
        ],
      ],
    ],
  ]);

  }
   public function actions(){
       $actions = parent::actions();
      unset( $actions['create']);
      return $actions;
   }
   public function actionCreate(){

       $model = new \common\models\Client();
       $transaction = Yii::$app->db->beginTransaction();
       try 
       {

        $model->load(Yii::$app->getRequest()->getBodyParams(), '');
        $user_create = \common\models\User::user_create($model);
        if($user_create){
           $model->user_id = $user_create->id;
          if($model->save()){
            $transaction->commit();
            return $model;
          }
        }

       }
        catch (Exception $e) 
        {
          $transaction->rollBack();
          return null;
        }    
   }
Here is my User Model
class User extends ActiveRecord implements IdentityInterface
{

    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }
    public function generateAccountActivationToken()
    {
        $this->account_activation_token = Yii::$app->security->generateRandomString() . '_' . time();
    }
    /**
     * @inheritdoc
     */
    // public static function findIdentityByAccessToken($token, $type = null)
    // {
    //     throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    // }
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['auth_key' => $token]);
    }
    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
    }

    /**
     * Finds user by password reset token
     *
     * @param string $token password reset token
     * @return static|null
     */
    public static function findByPasswordResetToken($token)
    {
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
        $parts = explode('_', $token);
        $timestamp = (int) end($parts);
        if ($timestamp + $expire < time()) {
            // token expired
            return null;
        }

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return $this->auth_key;
        // return null;

    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomKey();

    }


    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}

这里的问题是当我发送 post 请求时它返回 401 错误。我知道 这是身份验证错误,它甚至没有达到功能 公共静态函数 findIdentityByAccessToken($token, $type = null) { return static::findOne(['auth_key' => $token]); } 我知道问题出在 HttpBearerAuth::className()。我怎么能在这里解决这个错误是图像

【问题讨论】:

  • @Muhammad Omer Aslam 看看兄弟这里出了什么问题。用户控制器中的登录和 sinup 操作工作正常。如果我删除客户端中创建的操作也可以正常工作的行为,现在问题是在访问令牌处理 HttpBearerAuth::className().
  • 为你添加了答案

标签: rest yii yii2 yii2-api yii-inheritance


【解决方案1】:

关于声明

它甚至没有登陆findIdentityByAccessToken()

来自DOCS

身份验证后,对于每个 API 请求,请求的控制器将尝试在 它的beforeAction() 步骤。

如果认证成功,控制器将执行其他检查 (如限速、授权)然后运行动作。这 可以通过以下方式检索经过身份验证的用户身份信息 Yii::$app-&gt;user-&gt;identity.

如果身份验证失败,将发送 HTTP 状态 401 的响应 与其他适当的标题(例如 HTTP Basic Auth 的 WWW-Authenticate 标头)。

HttpBearerAuth 扩展了HttpHeaderAuth,这是一个通过HTTP Headers 支持HTTP 身份验证的操作过滤器,查看HttpHeaderAuth 函数authenticate($user, $request, $response) 的源代码,您将看到它首先获得了身份验证标头行

$authHeader = $request->getHeaders()->get($this->header);

并且仅当authHeaders 不是null 时才返回$identity,否则它会从authenticate($user, $request, $response) 方法返回null,并且您甚至没有登陆findIdentityByAccesToken() 就会收到401 错误。

你应该做的是

  • 打开postman并点击Authorization标签

  • 从下拉列表BearerToken 中选择Type

  • 在右侧为您发送请求的用户从用户表中添加auth_key

  • 点击Preview Request按钮,你会看到消息请求头被更新了

现在,如果您转到 Authorization 选项卡旁边的 Headers 选项卡,您将看到 @987654357 @一对授权头

现在单击发送按钮并查看您的请求,我建议您将当前操作中的所有内容都注释掉,只需添加 echo "hello"; 声明即可知道它已到达那里。


您可以通过以下方式通过 curl 发送标头进行身份验证

curl -d "param1=value1&param2=value2" 
-H "Content-Type: application/x-www-form-urlencoded" 
-H "Authorization: Bearer YOUR_TOKEN_" 
-X POST http://localhost:3000/data

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    相关资源
    最近更新 更多