1.
创建数据库表:
sql创建:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL COMMENT '用户名',
`password_hash` varchar(80) DEFAULT NULL COMMENT '密码',
`password_reset_token` varchar(60) DEFAULT NULL COMMENT '密码token',
`email` varchar(60) DEFAULT NULL COMMENT '邮箱',
`auth_key` varchar(60) DEFAULT NULL,
`status` int(5) DEFAULT NULL COMMENT '状态',
`created_at` int(18) DEFAULT NULL COMMENT '创建时间',
`updated_at` int(18) DEFAULT NULL COMMENT '更新时间',
`password` varchar(50) DEFAULT NULL COMMENT '密码',
`role` varchar(50) DEFAULT NULL COMMENT 'role',
`access_token` varchar(60) DEFAULT NULL,
`allowance` int(20) NOT NULL,
`allowance_updated_at` int(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `access_token` (`access_token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
--
-- 转存表中的数据 `user`
--
INSERT INTO `user` (`id`, `username`, `password_hash`, `password_reset_token`, `email`, `auth_key`, `status`, `created_at`, `updated_at`, `password`, `role`, `access_token`, `allowance`, `allowance_updated_at`) VALUES
(1, 'terry', '$2y$13$EyK1HyJtv4A/19Jb8gB5y.4SQm5y93eMeHjUf35ryLyd2dWPJlh8y', NULL, 'zqy234@126.com', 'pBJi3hyFsLsTuvUM9paFpWjYRatn3qwS', 10, 1441763620, 1447318986, NULL, NULL, 'xxxxxxxxxxxxxxxxxxxx', 0, 1447318986),
(2, 'terry1', '$2y$13$B0P2T4wEFrxeecSEClo5g.wrapMqG0RmsSL0cJluHJ747M3R0vkMG', NULL, 'zqy2341@126.com', 'wIvJk7dMm6PQ1dJFz8iUqJ1RfH6rsDTW', 10, 1441763906, 1441763906, NULL, NULL, NULL, 0, 0),
(3, 'zqy', '$2y$13$kcczJRoLGqSWHo7AZloCyeJiMYeM5SA1uXhyUZCNkFirWJuWeC3gO', NULL, 'zqy23114@126.com', 'K-76pcy7gxceemxRI2IeN5g1EhLMaCj8', 10, 1442544183, 1442544183, NULL, 'moderator', NULL, 0, 0),
(4, 'admin', '$2y$13$w4/PWXvwRUKNSrDTSMhPhOnvxw4v4WWt7GVl2siozPDlmEjP04vJC', NULL, 'zqy2342321@126.com', 'hZWOaamjHEsPtuJJVghFRdE2oTj7Qv8P', 10, 1446524232, 1446524232, NULL, NULL, NULL, 0, 0);
2.
设置用户组件 yii\web\User ;
'user' => [
'identityClass' => 'myapp\code\core\Erp\User\models\User',
# 'enableAutoLogin' => true,
],
3.创建User模块,在模块中加入
'user' =>
[
'class' => 'myapp\code\core\Erp\User\Module',
]
4.编辑 myapp\code\core\Erp\User\Module.php
<?php
namespace myapp\code\core\Erp\User;
use Yii;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'myapp\code\core\Erp\User\controllers';
public function init()
{
parent::init();
# session 设置无效
\Yii::$app->user->enableSession = false;
\Yii::$app->user->loginUrl = null;
# 加载配置文件
if(file_exists(__DIR__ . '/etc/config.php')){
Yii::configure($this, ['params'=>(require(__DIR__ . '/etc/config.php'))]);
}
$this->params['blockDir'] = str_replace("\\controllers","",$this->controllerNamespace);
}
}
主要是 设置:
\Yii::$app->user->enableSession = false;
\Yii::$app->user->loginUrl = null;
5.创建 myapp\code\core\Erp\User\models\User 实现 yii\web\IdentityInterface 接口。
代码如下:
<?php
namespace myapp\code\core\Erp\User\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use yii\filters\RateLimitInterface;
/**
* User model
*
* @property integer $id
* @property string $username
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property string $auth_key
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface ,RateLimitInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
# 速度控制 6秒内访问3次,注意,数组的第一个不要设置1,设置1会出问题,一定要
#大于2,譬如下面 6秒内只能访问三次
# 文档标注:返回允许的请求的最大数目及时间,例如,[100, 600] 表示在600秒内最多100次的API调用。
public function getRateLimit($request, $action){
return [3, 6];
}
# 文档标注: 返回剩余的允许的请求和相应的UNIX时间戳数 当最后一次速率限制检查时。
public function loadAllowance($request, $action){
//return [1,strtotime(date("Y-m-d H:i:s"))];
//echo $this->allowance;exit;
return [$this->allowance, $this->allowance_updated_at];
}
# allowance 对应user 表的allowance字段 int类型
# allowance_updated_at 对应user allowance_updated_at int类型
# 文档标注:保存允许剩余的请求数和当前的UNIX时间戳。
public function saveAllowance($request, $action, $allowance, $timestamp){
$this->allowance = $allowance;
$this->allowance_updated_at = $timestamp;
$this->save();
}
/**
* @inheritdoc
*/
# 设置table
public static function tableName()
{
return 'user';
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
/**
* @inheritdoc
*/
# 设置 status 默认 ,以及取值的区间
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
* @inheritdoc
*/
# 通过id 找到identity
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* @inheritdoc
*/
# 通过access_token 找到identity
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token, 'status' => self::STATUS_ACTIVE]);
}
# 生成access_token
public function generateAccessToken()
{
$this->access_token = Yii::$app->security->generateRandomString();
}
/**
* 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)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* @inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}
6.控制器:
<?php
namespace myapp\code\core\Erp\User\controllers;
use Yii;
use yii\web\Controller;
use myapp\code\core\Erp\User\models\User;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
use yii\filters\RateLimiter;
class IndexController extends Controller
{
public function init(){
parent::init();
}
# 行为 添加
# 验证 :authenticator
# 速度控制:rateLimiter
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
# 下面是三种验证access_token方式
//HttpBasicAuth::className(),
//HttpBearerAuth::className(),
# 这是GET参数验证的方式
# http://10.10.10.252:600/user/index/index?access-token=xxxxxxxxxxxxxxxxxxxx
QueryParamAuth::className(),
],
];
# rate limit部分,速度的设置是在
# \myapp\code\core\Erp\User\models\User::getRateLimit($request, $action){
/* 官方文档:
当速率限制被激活,默认情况下每个响应将包含以下HTTP头发送 目前的速率限制信息:
X-Rate-Limit-Limit: 同一个时间段所允许的请求的最大数目;
X-Rate-Limit-Remaining: 在当前时间段内剩余的请求的数量;
X-Rate-Limit-Reset: 为了得到最大请求数所等待的秒数。
你可以禁用这些头信息通过配置 yii\filters\RateLimiter::enableRateLimitHeaders 为false, 就像在上面的代码示例所示。
*/
$behaviors['rateLimiter'] = [
'class' => RateLimiter::className(),
'enableRateLimitHeaders' => true,
];
return $behaviors;
}
public function actionIndex()
{
echo Yii::$app->user->id;
}
}
7
然后通过访问:
http://10.10.10.252:900/user/index/index?access-token=nnnnnnnnnnnnnn
就可以访问了,由于我设置的是6秒内访问3次,正常访问,查看head消息头:如下
我设置的是:6秒内最多访问3次的返回结果
X-Rate-Limit-Limit : 3 总次数还剩余3次
X-Rate-Limit-Remaining:2 还剩余2次