yii2项目实战之restful api授权验证详解

2019-05-01 14:36:11王冬梅

我们用postman模拟请求访问下 /v1/users/user-profile?token=apeuT9dAgH072qbfrtihfzL6qDe_l4qz_1479626145发现,抛出了一个异常

"findIdentityByAccessToken" is not implemented.

这是怎么回事呢?

我们找到 yiifiltersauthQueryParamAuth 的authenticate方法,发现这里调用了 commonmodelsUser类的loginByAccessToken方法,有同学疑惑了,commonmodelsUser类没实现loginByAccessToken方法为啥说findIdentityByAccessToken方法没实现?如果你还记得commonmodelsUser类实现了yiiwebuser类的接口的话,你应该会打开yiiwebUser类找答案。没错,loginByAccessToken方法在yiiwebUser中实现了,该类中调用了commonmodelsUser的findIdentityByAccessToken,但是我们看到,该方法中通过throw抛出了异常,也就是说这个方法要我们自己手动实现!

这好办了,我们就来实现下commonmodelsUser类的findIdentityByAccessToken方法吧

public static function findIdentityByAccessToken($token, $type = null)
{
 // 如果token无效的话,
 if(!static::apiTokenIsValid($token)) {
  throw new yiiwebUnauthorizedHttpException("token is invalid.");
 }

 return static::findOne(['api_token' => $token, 'status' => self::STATUS_ACTIVE]);
 // throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}

验证完token的有效性,下面就要开始实现主要的业务逻辑部分了。

/**
 * 获取用户信息
 */
public function actionUserProfile ($token)
{
 // 到这一步,token都认为是有效的了
 // 下面只需要实现业务逻辑即可,下面仅仅作为案例,比如你可能需要关联其他表获取用户信息等等
 $user = User::findIdentityByAccessToken($token);
 return [
  'id' => $user->id,
  'username' => $user->username,
  'email' => $user->email,
 ];
}

服务端返回的数据类型定义

在postman中我们可以以何种数据类型输出的接口的数据,但是,有些人发现,当我们把postman模拟请求的地址copy到浏览器地址栏,返回的又却是xml格式了,而且我们明明在UserProfile操作中返回的是属组,怎么回事呢?

这其实是官方捣的鬼啦,我们一层层源码追下去,发现在yiirestController类中,有一个 contentNegotiator行为,该行为指定了允许返回的数据格式formats是json和xml,返回的最终的数据格式根据请求头中Accept包含的首先出现在formats中的为准,你可以在yiifiltersContentNegotiatornegotiateContentType方法中找到答案。

你可以在浏览器的请求头中看到

Accept:

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

相关文章 大家在看