原文:yii2 RESTful 接口 api -3 : 账户验证 和 速度控制
1.
创建数据库表:
sql创建:
-- phpMyAdmin SQL Dump
-- version 3.3.10
-- http://www.phpmyadmin.net
--
-- 主机: localhost
-- 生成日期: 2015 年 11 月 12 日 17:05
-- 服务器版本: 5.6.14
-- PHP 版本: 5.4.34
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- 数据库: `erp`
--
-- --------------------------------------------------------
--
-- 表的结构 `user`
--
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, '[email protected]', 'pBJi3hyFsLsTuvUM9paFpWjYRatn3qwS', 10, 1441763620, 1447318986, NULL, NULL, 'xxxxxxxxxxxxxxxxxxxx', 0, 1447318986),
(2, 'terry1', '$2y$13$B0P2T4wEFrxeecSEClo5g.wrapMqG0RmsSL0cJluHJ747M3R0vkMG', NULL, '[email protected]', 'wIvJk7dMm6PQ1dJFz8iUqJ1RfH6rsDTW', 10, 1441763906, 1441763906, NULL, NULL, NULL, 0, 0),
(3, 'zqy', '$2y$13$kcczJRoLGqSWHo7AZloCyeJiMYeM5SA1uXhyUZCNkFirWJuWeC3gO', NULL, '[email protected]', 'K-76pcy7gxceemxRI2IeN5g1EhLMaCj8', 10, 1442544183, 1442544183, NULL, 'moderator', NULL, 0, 0),
(4, 'admin', '$2y$13$w4/PWXvwRUKNSrDTSMhPhOnvxw4v4WWt7GVl2siozPDlmEjP04vJC', NULL, '[email protected]', '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',
]
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 接口。
代码如下:
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.控制器:
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:600/user/index/index?access-token=xxxxxxxxxxxxxxxxxxxx
就可以访问了,由于我设置的是6秒内访问3次,正常访问,查看head消息头:如下
我设置的是:6秒内最多访问3次的返回结果
X-Rate-Limit-Limit : 3 总次数还剩余3次
X-Rate-Limit-Remaining:2 还剩余2次