第一步:配置文件main.php
:
'components' => [
'user' => [
'identityClass' => 'api\models\User', // 用户认证类
'enableAutoLogin' => true,
'enableSession' => false,
],
'urlManager' => [
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'site',
'pluralize' => false,
'extraPatterns' => [ // 新增其它操作列表
'POST login' => 'login',
],
],
],
],
],
第二步:修改表结构,添加字段access_token
和access_token
:
`access_token` varchar(32) DEFAULT NULL COMMENT '认证令牌',
`expire_at` int(11) DEFAULT NULL COMMENT '认证过期时间戳',
第三步:用户认证类api\models\User.php
:
namespace api\models;
use Yii;
class User extends \common\models\User
{
/**
* 生成访问令牌
* @return string
* @throws \yii\base\Exception
*/
public function generateAccessToken()
{
$this->access_token = Yii::$app->security->generateRandomString();
return $this->access_token;
}
/**
* 判断访问令牌是否有效
* @param string $token
* @param null $type
* @return User|null
*/
public static function findIdentityByAccessToken($token, $type = null)
{
return static::find()
->where(['status' => self::STATUS_ACTIVE])
->andWhere(['access_token' => $token])
->andWhere(['>', 'expire_at', time()])
->limit(1)->one();
}
}
第四步:登录验证类api\models\LoginForm.php
:
namespace api\models;
use yii\base\Model;
class LoginForm extends Model
{
public $username;
public $password;
private $_user;
public function rules()
{
return [
[['username', 'password'], 'trim'],
[['username', 'password'], 'required'],
[['password'], 'validatePassword'],
];
}
public function attributeLabels()
{
return [
'username' => '用户名',
'password' => '密码',
];
}
public function validatePassword($attribute)
{
if(!$this->hasErrors()){
$user = $this->getUser();
if(!$user || !$user->validatePassword($this->password)){
$this->addError($attribute, 'Incorrect username or password.');
}
}
}
public function login()
{
if($this->validate()){
$accessToken = $this->_user->generateAccessToken();
$this->_user->expire_at = time() + 3600;
$this->_user->save(true, ['access_token', 'expire_at']);
return $accessToken;
}
return false;
}
protected function getUser()
{
if($this->_user === null){
$this->_user = User::findByUsername($this->username);
}
return $this->_user;
}
}
第五步:控制器登录方法api\controllers\SiteController.php
:
namespace api\controllers;
use Yii;
use api\models\LoginForm;
class SiteController extends \yii\rest\Controller
{
/**
* @return LoginForm|array
* @throws \yii\base\Exception
*/
public function actionLogin()
{
$model = new LoginForm();
$model->load(Yii::$app->request->post(), '');
if($model->login()){
return ['access_token' => $model->login()];
}
return $model;
}
}
第六步、控制器过滤认证:
namespace api\controllers;
use Yii;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\QueryParamAuth;
use yii\rest\ActiveController;
use api\models\User;
use common\helpers\ArrayHelper;
class ArticleController extends ActiveController
{
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticatior' => [
// 请求参数认证方式, 参数名为`access-token`
'class' => QueryParamAuth::className(),
// HTTP 基本认证,
/*'class' => HttpBasicAuth::className(),
'auth' => function($username, $password){
$user = User::find()->where(['username' => $username])->limit(1)->one();
if($user->validatePassword($password)){
return $user;
}
return null;
},*/
],
]);
}
}
第七步、小程序访问受限:
//wxml:
<view bindtap='bindLoginTap'>登录</view>
<view bindtap='bindReadTap'>受限访问文章列表</view>
//js:
bindReadTap: function () {
wx.request({
url: 'http://tongmengcms2.ccc/api/articles?access-token=nuIoikmH-uow2iw3VL_R0sCg5UzUjQYbn',
header: {
'Content-Type': 'application/json'
},
method: 'GET',
success: function (res) {
console.log(res.data);
}
})
},