ActiveController.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. namespace api\controllers;
  3. use Yii;
  4. use yii\filters\RateLimiter;
  5. use yii\filters\auth\CompositeAuth;
  6. use yii\filters\auth\HttpBasicAuth;
  7. use yii\filters\auth\HttpBearerAuth;
  8. use yii\filters\auth\HttpHeaderAuth;
  9. use yii\filters\auth\QueryParamAuth;
  10. use yii\web\BadRequestHttpException;
  11. use yii\web\UnauthorizedHttpException;
  12. use common\traits\BaseAction;
  13. use common\behaviors\HttpSignAuth;
  14. use common\enums\MemberTypeEnum;
  15. use common\enums\StatusEnum;
  16. use common\helpers\ArrayHelper;
  17. use common\helpers\StringHelper;
  18. use common\behaviors\TrafficShaperBehavior;
  19. /**
  20. * Class ActiveController
  21. * @package api\controllers
  22. * @author jianyan74 <751393839@qq.com>
  23. */
  24. class ActiveController extends \yii\rest\ActiveController
  25. {
  26. use BaseAction;
  27. /**
  28. * 不用进行登录验证的方法
  29. * 例如: ['index', 'update', 'create', 'view', 'delete']
  30. * 默认全部需要验证
  31. *
  32. * @var array
  33. */
  34. protected $authOptional = [];
  35. /**
  36. * 不用进行签名验证的方法
  37. * 例如: ['index', 'update', 'create', 'view', 'delete']
  38. * 默认全部需要验证
  39. *
  40. * @var array
  41. */
  42. protected $signOptional = [];
  43. /**
  44. * 用户类型
  45. *
  46. * @var int
  47. */
  48. protected $memberType = MemberTypeEnum::MEMBER;
  49. /**
  50. * 行为验证
  51. *
  52. * @return array
  53. */
  54. public function behaviors()
  55. {
  56. $behaviors = parent::behaviors();
  57. // 进行签名验证
  58. if (Yii::$app->params['user.httpSignValidity'] == true) {
  59. $behaviors['signTokenValidate'] = [
  60. 'class' => HttpSignAuth::class,
  61. 'optional' => $this->signOptional, // 不进行认证判断方法
  62. ];
  63. }
  64. $behaviors['authenticator'] = [
  65. 'class' => CompositeAuth::class,
  66. 'authMethods' => [
  67. /**
  68. * 下面是四种验证access_token方式
  69. *
  70. * 1.HTTP 基本认证: access token 当作用户名发送,应用在access token可安全存在API使用端的场景,例如,API使用端是运行在一台服务器上的程序。
  71. * \yii\filters\auth\HttpBasicAuth::class,
  72. *
  73. * 2.OAuth : 使用者从认证服务器上获取基于OAuth2协议的access token,然后通过 HTTP Bearer Tokens 发送到API 服务器。
  74. * header格式:Authorization:Bearer+空格+access-token
  75. * yii\filters\auth\HttpBearerAuth::class,
  76. *
  77. * 3.请求参数 access token 当作API URL请求参数发送,这种方式应主要用于JSONP请求,因为它不能使用HTTP头来发送access token
  78. * http://rageframe.com/user/index/index?access-token=123
  79. *
  80. * 4.请求参数 access token 当作API header请求参数发送
  81. * header格式: x-api-key: access-token
  82. * yii\filters\auth\HttpHeaderAuth::class,
  83. */
  84. // HttpBasicAuth::class,
  85. // HttpBearerAuth::class,
  86. HttpHeaderAuth::class,
  87. [
  88. 'class' => QueryParamAuth::class,
  89. 'tokenParam' => 'access-token',
  90. ],
  91. ],
  92. // 不进行认证判断方法
  93. 'optional' => $this->authOptional,
  94. ];
  95. /**
  96. * 请求速率控制
  97. *
  98. * limit部分,速度的设置是在common\models\common\RateLimit::getRateLimit($request, $action)
  99. * 当速率限制被激活,默认情况下每个响应将包含以下HTTP头发送 目前的速率限制信息:
  100. * X-Rate-Limit-Limit: 同一个时间段所允许的请求的最大数目;
  101. * X-Rate-Limit-Remaining: 在当前时间段内剩余的请求的数量;
  102. * X-Rate-Limit-Reset: 为了得到最大请求数所等待的秒数。
  103. * enableRateLimitHeaders:false: 不开启限制 true:开启限制
  104. */
  105. $behaviors['rateLimiter'] = [
  106. 'class' => RateLimiter::class,
  107. 'enableRateLimitHeaders' => true,
  108. ];
  109. if (Yii::$app->params['trafficShaperValidity'] == true) {
  110. // 令牌桶限流
  111. $behaviors['trafficShaper'] = [
  112. 'class' => TrafficShaperBehavior::class,
  113. 'enable' => true,
  114. ];
  115. }
  116. return $behaviors;
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. protected function verbs()
  122. {
  123. return [
  124. 'index' => ['GET', 'HEAD', 'OPTIONS'],
  125. 'view' => ['GET', 'HEAD', 'OPTIONS'],
  126. 'create' => ['POST', 'OPTIONS'],
  127. 'update' => ['PUT', 'PATCH', 'OPTIONS'],
  128. 'delete' => ['DELETE', 'OPTIONS'],
  129. ];
  130. }
  131. /**
  132. * 前置操作验证token有效期和记录日志和检查curd权限
  133. *
  134. * @param $action
  135. * @return bool
  136. * @throws BadRequestHttpException
  137. * @throws \yii\base\InvalidConfigException
  138. * @throws \yii\web\ForbiddenHttpException
  139. */
  140. public function beforeAction($action)
  141. {
  142. if (!parent::beforeAction($action)) {
  143. return false;
  144. }
  145. if (
  146. !Yii::$app->user->isGuest &&
  147. $this->memberType !== Yii::$app->user->identity->member_type
  148. ) {
  149. throw new UnauthorizedHttpException('未授权');
  150. }
  151. // 权限方法检查,如果用了rbac,请注释掉
  152. $this->checkAccess($action->id, $this->modelClass, Yii::$app->request->get());
  153. // 判断 IP 黑名单
  154. $blacklistOpen = Yii::$app->services->config->backendConfig('sys_ip_blacklist_open');
  155. if ($blacklistOpen == StatusEnum::ENABLED && !empty($blacklistIp = Yii::$app->services->config->backendConfig('sys_ip_blacklist'))) {
  156. $ipList = StringHelper::parseAttr($blacklistIp);
  157. if (ArrayHelper::ipInArray(Yii::$app->request->userIP, $ipList)) {
  158. // 记录行为日志
  159. Yii::$app->services->actionLog->create('visit', '限制IP访问', 0, [], false);
  160. throw new UnauthorizedHttpException('限制访问');
  161. }
  162. }
  163. // 每页数量
  164. $this->pageSize = Yii::$app->request->get('per-page', 10);
  165. $this->pageSize > 50 && $this->pageSize = 50;
  166. return true;
  167. }
  168. }
粤ICP备19079148号