Yii2-Api:如何为HttpBearer过滤器传递令牌

时间:2018-05-11 21:05:34

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

  

这是我的控制器

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;
    }
}
  

这里的问题是当我发送邮件请求时它返回401错误。我知道   它是认证错误它甚至没有击中功能       public static function findIdentityByAccessToken($ token,$ type = null)         {                   return static :: findOne([&#39; auth_key&#39; =&gt; $ token]);         }       我知道问题出在HttpBearerAuth :: className()。我如何在这里修复此错误的是图像   enter image description here

1 个答案:

答案 0 :(得分:1)

关于声明

  

它甚至没有落在findIdentityByAccessToken()

来自DOCS

  

经过身份验证后,适用于每个API   请求,请求的控制器将尝试验证用户   它的beforeAction()步骤。

     

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

     

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

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

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

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

你应该做的是

  • 打开postman,然后点击Authorization标签

enter image description here

  • 从下拉列表Type
  • 中选择BearerToken

enter image description here

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

enter image description here

  • 点击预览请求按钮,您将看到消息请求标题已更新

enter image description here

现在,如果您转到 Headers 标签旁边的 Authorization 标签,您将会请参阅key=>value对授权标题

enter image description here

现在点击发送按钮并查看您的请求我会建议您在当前操作中注释掉所有内容,只需添加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