150 lines
4.0 KiB
PHP
150 lines
4.0 KiB
PHP
<?php
|
||
/**
|
||
* @link http://www.yiiframework.com/
|
||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||
* @license http://www.yiiframework.com/license/
|
||
*/
|
||
|
||
namespace common\core;
|
||
|
||
use Yii;
|
||
use yii\filters\auth\HttpBearerAuth;
|
||
use yii\web\UnauthorizedHttpException;
|
||
use yii\web\Response;
|
||
use yii\web\Request;
|
||
use yii\web\User;
|
||
|
||
/**
|
||
* HttpBearerAuth is an action filter that supports the authentication method based on HTTP Bearer token.
|
||
*
|
||
* You may use HttpBearerAuth by attaching it as a behavior to a controller or module, like the following:
|
||
*
|
||
* ```php
|
||
* public function behaviors()
|
||
* {
|
||
* return [
|
||
* 'tokenAuth' => [
|
||
* 'class' => \common\core\TokenAuth::className(),
|
||
* ],
|
||
* ];
|
||
* }
|
||
* ```
|
||
*
|
||
* @author longfei <phphome@qq.com>
|
||
* @since 2.0
|
||
*/
|
||
class TokenAuth extends HttpBearerAuth
|
||
{
|
||
|
||
//public $optional = ['*'];
|
||
|
||
/**
|
||
* ---------------------------------------
|
||
* 功能说明
|
||
*
|
||
* @param \yii\base\Action $action
|
||
* @return bool
|
||
* @throws UnauthorizedHttpException
|
||
* @author hlf <phphome@qq.com> 2020/5/21
|
||
* ---------------------------------------
|
||
*/
|
||
public function beforeAction($action)
|
||
{
|
||
$response = $this->response ?: Yii::$app->getResponse();
|
||
|
||
try {
|
||
$identity = $this->authenticate(
|
||
$this->user ?: Yii::$app->getUser(),
|
||
$this->request ?: Yii::$app->getRequest(),
|
||
$response
|
||
);
|
||
} catch (UnauthorizedHttpException $e) {
|
||
if ($this->isOptional($action)) {
|
||
return true;
|
||
}
|
||
|
||
throw $e;
|
||
}
|
||
|
||
if ($identity !== null || $this->isOptional($action)) {
|
||
return true;
|
||
}
|
||
|
||
$this->challenge($response);
|
||
$this->handleFailure($response);
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* ---------------------------------------
|
||
* 验证当前用户
|
||
*
|
||
* @param User $user
|
||
* @param Request $request
|
||
* @param Response $response
|
||
* @return null|\yii\web\IdentityInterface
|
||
* @throws UnauthorizedHttpException
|
||
* @author hlf <phphome@qq.com> 2020/5/21
|
||
* ---------------------------------------
|
||
*/
|
||
public function authenticate($user, $request, $response)
|
||
{
|
||
// 当 $identity = null 时表示无法获取的认证信息或者认证失败
|
||
// $identity = null 时为游客
|
||
// $identity = parent::authenticate($user, $request, $response);
|
||
$authHeader = $request->getHeaders()->get($this->header);
|
||
|
||
if ($authHeader !== null) {
|
||
if ($this->pattern !== null) {
|
||
if (preg_match($this->pattern, $authHeader, $matches)) {
|
||
$authHeader = $matches[1];
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
$identity = $user->loginByAccessToken($authHeader, get_class($this));
|
||
if ($identity === null) {
|
||
$this->challenge($response);
|
||
$this->handleFailure($response);
|
||
}
|
||
|
||
return $identity;
|
||
}
|
||
|
||
return null;
|
||
|
||
}
|
||
|
||
/**
|
||
* ---------------------------------------
|
||
* 身份认证失败时
|
||
* 例如,可以生成一些适当的HTTP头。
|
||
*
|
||
* @param Response $response
|
||
* @author hlf <phphome@qq.com> 2020/5/21
|
||
* ---------------------------------------
|
||
*/
|
||
public function challenge($response)
|
||
{
|
||
$response->getHeaders()->set('WWW-Authenticate', "Bearer realm=\"{$this->realm}\"");
|
||
|
||
}
|
||
|
||
/**
|
||
* ---------------------------------------
|
||
* 处理身份认证失败
|
||
* 通常应该抛出UnauthorizedHttpException以指示身份验证失败。
|
||
*
|
||
* @param Response $response
|
||
* @throws UnauthorizedHttpException
|
||
* @author hlf <phphome@qq.com> 2020/5/21
|
||
* ---------------------------------------
|
||
*/
|
||
public function handleFailure($response)
|
||
{
|
||
throw new UnauthorizedHttpException(Yii::t('api', 'Token权限认证失败'));
|
||
}
|
||
}
|