授权验证详解,Yii框架分页完结格局详解

Yii是基于PHP语言塑造的一款框架,精晓PHP的同学对那款框架确定也不会目生。而自己在近些日子应用yii2写App接口的时,查看官方了的RESTful Web服务文书档案,文书档案中对此授权验证的历程有像这种类型叁个介绍:

何以是restful风格的api呢?大家事先有写过大篇的稿子来介绍其定义以及基本操作。

注册

本文实例汇报了Yii框架分页完毕格局。分享给大家供我们参谋,具体如下:

如果你系那个支持以上3个认证方式,可以使用CompositeAuth,如下所示:use yiifiltersauthCompositeAuth;use yiifiltersauthHttpBasicAuth;use yiifiltersauthHttpBearerAuth;use yiifiltersauthQueryParamAuth;public function behaviors(){ $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ 'class' => CompositeAuth::className(), 'authMethods' => [ HttpBasicAuth::className(), HttpBearerAuth::className(), QueryParamAuth::className(), ], ]; return $behaviors;}authMethods 中每个单元应为一个认证方法名或配置数组。findIdentityByAccessToken()方法的实现是系统定义的, 例如,一个简单的场景,当每个用户只有一个access token, 可存储access token 到user表的access_token列中, 方法可在User类中简单实现,如下所示:use yiidbActiveRecord;use yiiwebIdentityInterface;class User extends ActiveRecord implements IdentityInterface{ public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['access_token' => $token]); }}

既是写过了,那明日是要说点什么吗?

在advanced模板中,踏入frontend/index.php?r=site/signup页面,能够观察框架的注册页面

下家公司用的框架是yii,近日看了下有关课程,今儿把分页教程写下,最终把tp的分页也给整合进了yii,因为个人认为yii分页未有tp用的随手。

上述是合丹麦语档的初稿,而自个儿随即整合本人的API接口,感到最适合本身动用的是第二种QueryParamAuth品类的印证,便是在伸手的url中拼接上AccessToken。那也是大范围的一种鉴权格局,而完成那些申明,框架又要求我们成功findIdentityByAccessToken()函数,所以为了不稀里糊涂的跟着文书档案弄完了,作者主宰从源码里查究一下贯彻鉴权的历程中毕竟发生了怎么样。

那篇作品主要针对实际场景中api的配备来写。

图片 1

首页,在models目录里成立个Auth.php的模子文件,里面写入

至于哪些促成那个历程,以及完结认证,小编事先在网络一度见到有恢宏博客写那一个了,所以在此笔者也不再赘言。

大家明天就来大大的侃侃那多少个年api遇到的授权验证难题!独家干活,要是看完全部收益,记得不要忘记给自个儿点赞哦。

填写完Username、Email和Password后点击Signup后,假设格式不对,frontend/models/SignuForm中的rules()函数会进展开头证实,全数格式正确后,数据传输到 frontend/controllers /SiteController中的 actionSignup()函数中,函数加载客户输入的挂号音信,在frontend/models/SignupForm中的signup()函数,

class Auth extends CActiveRecord {
  public static function model($className = __CLASS__) {
    return parent::model($className);
  }
  public function tableName() {
    return '{{auth}}';
  }
}

先是我们步入QueryParamAuth类里,里面有贰个authenticate($user, $request, $response)函数,那些函数的代码是那般的:

事务分析

以下引述的文字为解释函数中的具体细节,不读书不影响总体,因为从没折叠文字功效,故选择援引的秘籍,下同

继之在controllers目录里创制IndexController.php的决定文件,里面写入

public function authenticate($user, $request, $response){ // 获取get参数里的access-token, $this->tokenParam的具体名称,可以在类中指定 $accessToken = $request->get($this->tokenParam); if (is_string($accessToken)) { //存在登录令牌的情况下,执行yiiwebuser类里的loginByAccessToken方法 $identity = $user->loginByAccessToken($accessToken, get_class; if ($identity !== null) { return $identity; } } //没有accessToken直接报错 if ($accessToken !== null) { $this->handleFailure($response); } return null;}

咱们先来打探一下一体逻辑

if (!$this->validate()) {
  return null;
}
class IndexController extends Controller {
  public function actionList() {
    $criteria = new CDbCriteria();
    $criteria->order = 'a_id desc';
    $count = Auth::model()->count($criteria);
    $page = new CPagination($count);
    $page->pageSize = 10;
    $page->applyLimit($criteria);
    $auth = Auth::model()->findAll($criteria);
    $this->renderPartial('auth', array('page' => $page, 'list' => $auth));
  }
  public function actionList1() {
    $p = isset($_GET['page']) ? $_GET['page'] : 0;
    $criteria = new CDbCriteria();
    $criteria->select = "a_id,a_nickname";
    $criteria->condition='';
    $criteria->limit = 10;
    $criteria->offset = $p == 0 ? 0 : (($p-1)*10);
    $criteria->order = 'a_id desc';
    $auth = Auth::model()->findAll($criteria);
    $count = Auth::model()->count($criteria);
    $page = new CPagination($count);
    $page->pageSize = 10;
    $page->applyLimit($criteria);
    $this->renderPartial('auth', array('page' => $page, 'list' => $auth));
  }
}

自己把这段源码的注释直接附在代码中,在此间我们能差不离知道那一个函数做了什么样工作,可是里面$user, $request, $response那三个参数又是什么获得传递步向的吧。大家再步向QueryParamAuth的父类AuthMethod里一探终究。

1.客户在客商端填写登入表单
2.客商提交表单,顾客端央浼登陆接口login
3.服务端校验客商的帐号密码,并赶回三个可行的token给客商端
4.顾客端得到客户的token,将之存款和储蓄在顾客端举个例子cookie中
5.客商端辅导token访问供给校验的接口举个例子获取客户个人信息接口
6.服务端校验token的得力,校验通过,反正重临客商端须求的音讯,校验失利,须求客户重新登入

signup() 函数首先调用 yii2/base/Model中的validate() 函数进行认证
率先步,清除使用frontend/models/SignuForm中的rules()函数在顾客输入时的错误音讯

个中actionList和actionList1是$criteria的二种写法

开垦这么些父类,大家能看出$user, $request, $response这四个参数是父类中定义的七个精晓属性。而在父类中的beforeAction()中,获取到那四个法子,

本文大家以客商登录,获取顾客的个人音讯为例进行详细的欧洲经济共同体版表明。

if ($clearErrors) {
  $this->clearErrors();
}

最终在views目录里增添index目录,并在index目录内增添auth.php文件,里面写入

public function beforeAction{ $response = $this->response ?: Yii::$app->getResponse(); try { // 这里是重点,父类获取三个参数,传入我们之前的authenticate()函数中。 $identity = $this->authenticate( $this->user ?: Yii::$app->getUser(), $this->request ?: Yii::$app->getRequest(), $response ); } catch (UnauthorizedHttpException $e) { if ($this->isOptional { return true; } throw $e; } if ($identity !== null || $this->isOptional { return true; } $this->challenge($response); $this->handleFailure($response); return false;}

以上,就是大家本篇文章要完成的根本。先别激动,也别恐慌,解析好了今后,细节部分大家再足履实地走下去。

其次步,beforeValidate()函数触发beforeValidate事件并赶回true
第三步,设置scenario,默认是default
第四步,因为此地的$attributeNames为null,

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<div class="blogList">
<ul>
  <?php foreach($list as $key=>$value){ ?>
  <li>
    <a><?php echo $value['a_nickname'];?></a>
  </li>
  <?php } ?>
</ul>
</div>
<div id="page">
<?php
  $this->widget('CLinkPager',array(
    'firstPageLabel'=>'首页',
    'lastPageLabel'=>'末页',
    'prevPageLabel'=>'上一页',
    'nextPageLabel'=>'下一页',
    'pages'=>$page,
    'maxButtonCount'=>13,
    )
  );
?>
</div>

大家得以看到,在beforeAction()函数中收获了参数,何况调用了authenticate函数,开端实行认证进度。今后大家知道了参数的原故,那么我们随后回到QueryParamAuth类里的authenticate()函数中,研讨鉴权进度。

有备无患专门的工作

$attributeNames = $this->activeAttributes();

上边是yii自带的写法,这里引入tp的分页类,做个大致的改动,步骤如下

authenticate()函数中大家看出有像这种类型一行代码:

1.您应有有三个api应用.
2.对于顾客端,大家计划使用postman实行模拟,倘使您的google浏览器还不曾安装postman,请先活动下载
3.要测量检验的客户表供给有贰个api_token的字段,未有的请先自行增多,并保障该字段充足长度
4.api应用开启了路由美化,并先配置post类型的login操作和get类型的signup-test操作
5.关闭了user组件的session会话

实行后赶回

第一,把tp的AjaxPage.class.php和Page.class.php移动到yii的类型目录下的 protected/components下边,况兼把文件名称分布改为AjaxPage.php和Page.php,分别步入三个公文,把内部的C方法去掉,约等于这一句

$identity = $user->loginByAccessToken($accessToken, get_class;

关于地方希图专门的学问的第4点和第5点,大家贴一下代码方便清楚

array(3) { [0]=> string(8) "username" [1]=> string(5) "email" [2]=> string(8) >"password" }

$this->varPage = C('VAR_PAGE') ? C('VAR_PAGE') : 'p' ;

在此间笔者提示我们,那些$user指的是yiiwebuser这几个类,而自己从前看来众多互连网教程让大家去完毕loginByAccessToken()其一函数,很几个人在落实了那么些函数之后问,为何不调用那么些函数,其实那个函数是绝非要求落成的,倘令你势需要完成那个函数,那么您就得把这里运用的$user替换来你和谐的User类,因为在那个时候,还不会调用你在config里布置的user类,非常多校友有了问题,照旧要先看看源码,并非意识那篇博客不行,就换另三个博客试试。。。

'components' => [
 'user' => [ 
  'identityClass' => 'commonmodelsUser',
  'enableAutoLogin' => true,
  'enableSession' => false,
 ],
 'urlManager' => [
  'enablePrettyUrl' => true,
  'showScriptName' => false,
  'enableStrictParsing' => true,
  'rules' => [
   [
    'class' => 'yiirestUrlRule',
    'controller' => ['v1/user'],
    'extraPatterns' => [
     'POST login' => 'login',
     'GET signup-test' => 'signup-test',
    ]
   ],
  ]
 ],
 // ......
],

第五步,$this->getActiveValidators()会收获frontend/models/SignuForm中的rules()中11条表达法则给validateAttributes()举行验证

改为

我们来一齐拜谒loginByAccessToken()函数的代码:

signup-test操作我们前边增添测验顾客,为记名操作提供有利。别的品种的操作前边看需求再做增多。

第六步,实施afterValidate()函数触发afterValidate事件

$this->varPage = 'p' ;
public function loginByAccessToken($token, $type = null){ /* @var $class IdentityInterface */ // 这里的identityClass才是我们在config中配置的那个User类 $class = $this->identityClass; //这里开始执行我们在User类中实现的findIdentityByAccessToken()函数 $identity = $class::findIdentityByAccessToken($token, $type); //这里的条件,在鉴权之前,我们得是登录状态 if ($identity && $this->login($identity)) { return $identity; } // 否则 就算有这个用户,但是不是登录状态 一样不能通过验证 return null;}

认证类的挑选

末尾 假使具备验证都由此,$this->hasErrors()为false,所以函数最终回到true

改完之后,那么些三个文本是无需引进的,因为yii在运行时会自行加载的。具体的可知protected/config.php/main.php的配置中的

自己早就把整个函数的分析写在解说里了,在这么些函数里会调用大家在config里安排的User类,何况去推行文书档案中让大家配备的findIdentityByAccessToken()函数,所以大家写的函数在那时才会派上用场,同时大家还得是登入意况工夫经过鉴权,登陆的话这里先不开展讲了,能够先用yii框架暗中同意页面包车型地铁报到就会透过。

我们在apimodulesv1controllersUserController中设定的model类指向 commonmodelsUser类,为了注脚入眼这里大家就不独立拿出去重写了,看各位供给,有须求的话再单独copy三个User类到apimodels下。

我们看一下数据表user的字段

// autoloading model and component classes
  'import'=>array(
    'application.models.*',
    'application.components.*',
  ),

至此,我们的报到鉴权就曾经经过了,要是不通过的小同伴,能够再消化摄取一下地点的源码剖判,相信你势必能查到题目毕竟出现在哪一步的。

校验顾客权限大家以 yiifiltersauthQueryParamAuth 为例

图片 2

其次,在protected/config.php/目录里新建多少个common.php文件,这些文件就放些项指标公物函数,熟稔tp的意中人应该精通tp也可能有集体函数文件,很好用,这里借鉴下,yii应该也可以有吗,近来还没觉察。在该公文写入

use yiifiltersauthQueryParamAuth;

public function behaviors() 
{
 return ArrayHelper::merge (parent::behaviors(), [ 
   'authenticator' => [ 
    'class' => QueryParamAuth::className() 
   ] 
 ] );
}

客户输入了username、password和email,Yii2框架是什么生成任何的字段的吧,先看password_hash,在SignupFrom中的signup函数中的密码生成是setPassword函数,该函数在common/models/User中,setPassword函数调用了yii2/base/Security中的每一条准则generatePasswordHash函数。

// 根据页码获取列表
function getListByPage($model, $select = '*', $condition = '', $limit = 10, $order = '', $p = '', $ajax = 0) {
  // 初始化参数
  $_GET['p'] = isset($_GET['p']) ? intval($_GET['p']) : 1;
  $limit = intval($limit) > 0 ? intval($limit) : 10;
  if ($p) {
    $_GET['p'] = intval($p) ? intval($p) : 1;
  }
  $criteria = new CDbCriteria();
  $count = $model->count($criteria);
  if ($ajax) {
    $Page = new AjaxPage($count, $limit);
  } else {
    $Page = new Page($count, $limit);
  }
  $result['page'] = trim($Page->show());
  $criteria->select = $select;
  $criteria->condition = $condition;
  $criteria->limit = $Page->listRows;
  $criteria->offset = $Page->firstRow;
  $criteria->order = $order;
  $list = $model->findAll($criteria);
  $result['list'] = $list;
  return $result;
}

如此一来,那岂不是全部访谈user的操作都亟待表达了?那特别,顾客端第贰个访谈login操作的时候哪来的token,yiifiltersauthQueryParamAuth对外提供壹性格质,用于过滤没有须求证实的action。大家将UserController的behaviors方法稍作修改

if (function_exists('password_hash')) {
  /** @noinspection PhpUndefinedConstantInspection */
  return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
}

其一文件可就要引进了,否则加载不了,能够在品种的入口文件index.php里活动引进,代码如下

public function behaviors() 
{
 return ArrayHelper::merge (parent::behaviors(), [ 
   'authenticator' => [ 
    'class' => QueryParamAuth::className(),
    'optional' => [
     'login',
     'signup-test'
    ],
   ] 
 ] );
}

如果有,就使用password_hash函数举行加密,倘诺PHP未有password_hash函数,就选拔crypt函数加密,初叶判别应该是为着协作PHP低于5.5的版本,究竟大于5.5的本子才起来有password_hash函数

require_once(dirname($config) . '/common.php');

如此login操作就不需求权限验证就可以访问了。

common/models/User的signup()函数在对password加密后,就能够持续生成多少个auth key,auth key是当客商在登陆的时候点击 remember me的时候的注脚消息,

最后在indexController.php中用到分页的地点调用该方法

累加测量试验顾客

auth key生成的不二诀要也是在yii2/base/Security中的generateRandomString,generateRandomString调用generateRandomKey函数,若是你的PHP版本为是5.2~5.6或许是7,那就是用random_bytes生成多个34个字节的字符串,若是还是不是,当您用的类别时windows并且安装了OpenSSL,就能够调用openssl_random_pseudo_bytes函数生成,要是您未设置OpenSSL,就能够动用mcrypt_create_iv生成。

public function actionPage() {
    $model = Auth::model();
    $info = getListByPage($model);
    $this->renderPartial('page', array('info' => $info));
}

为了防止让顾客端登入战败,我们先写三个简练的主意,往user表里面插入两条数据,便于接下去的校验。 

设若你使用的连串不是windows,就要求调用/dev/urandom,FreeBSD系统极其,会调用/dev/random,然后调用stream_set_read_buffer方法生成8字节的字符文件,生成后,通过fread函数读取该公文中的叁15个字节,然后再次来到该数额。
password_reset_token在顾客注册的时候是为空的,当顾客忘记密码在登陆页面点击reset it 后变化的,用来给用法发送邮件后重新设置密码时开展验证。

装进了此情势,以往调用分页时,只需传多少个参数,轻易又便捷。在page.php页面上调用

UserController增加signupTest操作,注意此方法不属于讲授范围之内,我们仅用于方便测验。

status 在common/models/User中定义的

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<div class="blogList">
<ul>
  <?php foreach($info['list'] as $key=>$value){ ?>
  <li>
    <a><?php echo $value['a_nickname'];?></a>
  </li>
  <?php } ?>
</ul>
</div>
<div id="page">
<?php
  echo $info['page'];
?>
</div>
use commonmodelsUser;
/**
 * 添加测试用户
 */
public function actionSignupTest ()
{
 $user = new User();
 $user->generateAuthKey();
 $user->setPassword('123456');
 $user->username = '111';
 $user->email = '111@111.com';
 $user->save(false);

 return [
  'code' => 0
 ];
}

const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;

同期选择findAll也得以兑现分页的询问功能,代码如下

如上,我们加多了二个username是111,密码是123456的客户

顾客注册时rules中的status默感到为10,
created_time和updated_time也是在common/models/User中的behaviors()函数中生成

function getListByPage($model, $select = '*', $condition = '', $limit = 10, $order = '', $p = '', $ajax = 0) {
  if (!$model) {
    return array();;
  }
  // 初始化参数
  $_GET['p'] = isset($_GET['p']) ? intval($_GET['p']) : 1;
  $limit = intval($limit) > 0 ? intval($limit) : 10;
  if ($p) {
    $_GET['p'] = intval($p) ? intval($p) : 1;
  }
  $count = $model->count();
  if ($ajax) {
    $Page = new AjaxPage($count, $limit);
  } else {
    $Page = new Page($count, $limit);
  }
  $result['page'] = trim($Page->show());
  $result['list'] = $model->findAll(array(
    'select'    => $select,
    'condition'   => $condition,
    'order'     => $order,
    'limit'     => $Page->listRows,
    'offset'     => $Page->firstRow,
  ));
  return $result;
}

签到操作

客商的数目证实合格,加上框架生成的数码,然后存款和储蓄进多少的user表里。

总结:

只要客户在客商端输入客户名和密码举办登入,服务端login操作实际很轻巧,超越四分之二的作业逻辑管理都在apimodelsloginForm上,来先看看login的落到实处

登录

经历过ci、tp四个框架后,再看yii进程快相当多。通晓某些框架,个人认为只有正是精通mvc的运用准绳,在model层调用数据库方法获得数码,controller层调用model层数据并张开逻辑管理,再传给view层,同期理解框架的沙盘操作,表单操作,分页操作,文件上传操作,cookie和session操作,url调用,那一个领会了,在通过项目标磨合,就基本上了,掌握了常用操作之后,再去会见源码,比较并总括框架间的区分和共性,进而升高本身的本事,未来常用开采就不言而谕,拿可观的薪饷也是如此。

use apimodelsLoginForm;

/**
 * 登录
 */
public function actionLogin ()
{
 $model = new LoginForm;
 $model->setAttributes(Yii::$app->request->post());
 if ($user = $model->login()) {
  if ($user instanceof IdentityInterface) {
   return $user->api_token;
  } else {
   return $user->errors;
  }
 } else {
  return $model->errors;
 }
}

关于frontend/controllers/SiteController中的actionSignup()中的

更加多关于Yii相关内容感兴趣的读者可查阅本站专项论题:《Yii框架入门及常用本领计算》、《php杰出开拓框架总计》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总计》、《php mysql数据库操作入门教程》及《php常见数据库操作才干汇总》

登陆成功后这里给顾客端重返了客商的token,再来看看登陆的实际逻辑的达成

if (Yii::$app->getUser()->login($user)) {
  return $this->goHome();
}

梦想本文所述对大家基于Yii框架的PHP程序设计有所支持。

新建apimodelsLoginForm.PHP

不怕客商注册后,那时该顾客的数量现已写入数据库了,最首先登场录的历程了

你也许感兴趣的作品:

  • Yii编制程序开垦常见调用手艺集锦
  • Yii2完结跨mysql数据库关联合检查询排序作用代码
  • Yii2达成多域名跨域同步登入退出
  • Yii2下session跨域名存活的解决方案
  • Yii基于数组和对象的Model查询本领实例详解
  • Yii学习计算之数据访谈对象 (DAO)
  • Yii框架落成的验证码、登入及退出职能示例
  • Yii框架完结图片上传的秘籍详解
  • Yii框架使用魔术点子完成跨文件调用功能示例
<?php
namespace apimodels;

use Yii;
use yiibaseModel;
use commonmodelsUser;

/**
 * Login form
 */
class LoginForm extends Model
{
 public $username;
 public $password;

 private $_user;

 const GET_API_TOKEN = 'generate_api_token';

 public function init ()
 {
  parent::init();
  $this->on(self::GET_API_TOKEN, [$this, 'onGenerateApiToken']);
 }


 /**
  * @inheritdoc
  * 对客户端表单数据进行验证的rule
  */
 public function rules()
 {
  return [
   [['username', 'password'], 'required'],
   ['password', 'validatePassword'],
  ];
 }

 /**
  * 自定义的密码认证方法
  */
 public function validatePassword($attribute, $params)
 {
  if (!$this->hasErrors()) {
   $this->_user = $this->getUser();
   if (!$this->_user || !$this->_user->validatePassword($this->password)) {
    $this->addError($attribute, '用户名或密码错误.');
   }
  }
 }
 /**
  * @inheritdoc
  */
 public function attributeLabels()
 {
  return [
   'username' => '用户名',
   'password' => '密码',
  ];
 }
 /**
  * Logs in a user using the provided username and password.
  *
  * @return boolean whether the user is logged in successfully
  */
 public function login()
 {
  if ($this->validate()) {
   $this->trigger(self::GET_API_TOKEN);
   return $this->_user;
  } else {
   return null;
  }
 }

 /**
  * 根据用户名获取用户的认证信息
  *
  * @return User|null
  */
 protected function getUser()
 {
  if ($this->_user === null) {
   $this->_user = User::findByUsername($this->username);
  }

  return $this->_user;
 }

 /**
  * 登录校验成功后,为用户生成新的token
  * 如果token失效,则重新生成token
  */
 public function onGenerateApiToken ()
 {
  if (!User::apiTokenIsValid($this->_user->api_token)) {
   $this->_user->generateApiToken();
   $this->_user->save(false);
  }
 }
}

报到的进程在yii2/web/User里的login()函数中

咱俩回过头来看一下,当大家在UserController的login操作中调用LoginForm的login操作后都发生了什么样

先是步,施行beforeLogin()函数触发beforeLogin事件
其次步,switchIdentity()函数把个人音讯换来当下顾客的消息,把具有的cookie都销毁,然后把当下客商的音信都存入到session和cookie中
其三步,获取当前顾客的id和客商登入的ip,并写入到log中
第四步,试行afterLogin()函数触发afterLogin事件

1、调用LoginForm的login方法

最后 返回true

2、调用validate方法,随后对rules实行校验

认清登入成功后,return $this->goHome();跳转到主页。

3、rules校验中调用validatePassword方法,对客户名和密码举办校验

你也许感兴趣的篇章:

  • Yii2达成多域名跨域同步登陆退出
  • Yii第22中学OAuth扩充及QQ互联登陆已毕格局
  • YII2自动登入Cookie总是失效的减轻办法
  • 修改yii2.0顾客登入使用的user表为别的的表完结形式(推荐)
  • 从零开首学YII2框架(一)通过Composer安装Yii2框架
  • 从零起初学YII2框架(五)神速转移代码工具 Gii 的行使
  • 从零开端学YII2框架(六)高级应用程序模板
  • 从零开头学YII2框架(二)通过 Composer 安装增加插件
  • 从零发轫学YII2框架(三)扩充插件yii2-gird
  • 从零开头学YII2框架(四)扩充插件yii2-kartikgii
  • Yii2框架实现登入、退出及自动登陆效率的艺术详解

4、validatePassword方法校验的历程中调用LoginForm的getUser方法,通过commonmodelsUser类的findByUsername获取客户,找不到可能commonmodelsUser的validatePassword对密码校验失利则赶回error

5、触发LoginForm::GENERATE_API_TOKEN事件,调用LoginForm的onGenerateApiToken方法,通过commonmodelsUser的apiTokenIsValid校验token的一蹴而就,如果不算,则调用User的generateApiToken方法重复生成

注意commonmodelsUser类必得是客商的印证类.

上边补充本节扩充的commonmodelsUser的连锁方法

/**
 * 生成 api_token
 */
public function generateApiToken()
{
 $this->api_token = Yii::$app->security->generateRandomString() . '_' . time();
}

/**
 * 校验api_token是否有效
 */
public static function apiTokenIsValid($token)
{
 if (empty($token)) {
  return false;
 }

 $timestamp = (int) substr($token, strrpos($token, '_')   1);
 $expire = Yii::$app->params['user.apiTokenExpire'];
 return $timestamp   $expire >= time();
}

一连补充apiTokenIsValid方法中涉嫌到的token保质期,在apiconfigparams.php文件内增添就能够

<?php
return [
 // ...
 // token 有效期默认1天
 'user.apiTokenExpire' => 1*24*3600,
];

到此处吧,顾客端登入 服务端重返token给顾客端就完成了。

遵照文中一齐首的深入分析,客商端应该把获得到的token存到地面,举个例子cookie中。未来再须要token校验的接口访谈中,从地面读取譬如从cookie中读取并拜见接口就可以。

依赖token央浼客商的验证操作

设若我们已经把收获到的token保存起来了,我们再以访谈客商音信的接口为例。

yiifiltersauthQueryParamAuth类确定的token参数是 access-token,大家得以在展现中期维修改下

public function behaviors() 
{
 return ArrayHelper::merge (parent::behaviors(), [ 
   'authenticator' => [ 
    'class' => QueryParamAuth::className(),
    'tokenParam' => 'token',
    'optional' => [
     'login',
     'signup-test'
    ],
   ] 
 ] );
}

此地将私下认可的access-token修改为token。

我们在配备文件的urlManager组件中追加对userProfile操作

'extraPatterns' => [
 'POST login' => 'login',
 'GET signup-test' => 'signup-test',
 'GET user-profile' => 'user-profile',
]

我们用postman模拟诉求访谈下 /v1/users/user-profile?token=apeuT9dAgH072qbfrtihfzL6qDe_l4qz_1479626145开采,抛出了八个特别

"findIdentityByAccessToken" is not implemented.

那是怎么回事呢?

我们找到 yiifiltersauthQueryParamAuth 的authenticate方法,发掘此处调用了 commonmodelsUser类的loginByAccessToken方法,有同学疑忌了,commonmodelsUser类没实现loginByAccessToken方法为什么说findIdentityByAccessToken方法没兑现?假诺您还记得commonmodelsUser类完毕了yiiwebuser类的接口的话,你应该会张开yiiwebUser类找答案。没有错,loginByAccessToken方法在yiiwebUser中贯彻了,该类中调用了commonmodelsUser的findIdentityByAccessToken,不过大家看出,该办法中经过throw抛出了分外,也正是说这一个办法要大家自身手动达成!

那好办了,大家就来促成下commonmodelsUser类的findIdentityByAccessToken方法吧

public static function findIdentityByAccessToken($token, $type = null)
{
 // 如果token无效的话,
 if(!static::apiTokenIsValid($token)) {
  throw new yiiwebUnauthorizedHttpException("token is invalid.");
 }

 return static::findOne(['api_token' => $token, 'status' => self::STATUS_ACTIVE]);
 // throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}

表明完token的管事,上边将在发轫兑现重大的事务逻辑部分了。

/**
 * 获取用户信息
 */
public function actionUserProfile ($token)
{
 // 到这一步,token都认为是有效的了
 // 下面只需要实现业务逻辑即可,下面仅仅作为案例,比如你可能需要关联其他表获取用户信息等等
 $user = User::findIdentityByAccessToken($token);
 return [
  'id' => $user->id,
  'username' => $user->username,
  'email' => $user->email,
 ];
}

服务端重返的数据类型定义

在postman中我们得以以何种数据类型输出的接口的多少,但是,有些人察觉,当大家把postman模拟央浼的地址copy到浏览器地址栏,再次回到的又却是xml格式了,况且我们明显在UserProfile操作中回到的是属组,怎么回事呢?

那实际是官方捣的鬼啦,大家一层层源码追下去,发掘在yiirestController类中,有一个contentNegotiator行为,该行为钦点了允许再次回到的数码格式formats是json和xml,重回的最后的数额格式依照央求头中Accept包括的第一出现在formats中的为准,你能够在yiifiltersContentNegotiator的negotiateContentType方法中找到答案。

你能够在浏览器的央求头中看到

Accept:

text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8

即application/xml首先现身在formats中,所以回来的数目格式是xml类型,若是客商端获取到的数码格式想遵纪守法json举办深入分析,只供给设置央浼头的Accept的值等于application/json就可以

有同学恐怕要说,那样太费事了,啥时期了,哪个人还用xml,笔者就想服务端输出json格式的数码,如何是好?

方式正是用来化解难点滴,来走访怎么办。apiconfigmain.php文件中扩张对response的配置

'response' => [
 'class' => 'yiiwebResponse',
 'on beforeSend' => function ($event) {
  $response = $event->sender;
  $response->format = yiiwebResponse::FORMAT_JSON;
 },
],

那般,不管你顾客端传什么,服务端最后输出的都会是json格式的多寡了。

自定义错误处理机制

再来看别的一个比较常见的主题材料:

您看大家地点多少个法子哈,重回的结果是二种多样的,那样就给客商端深入分析扩展了干扰,并且借使有那三个抛出,再次回到的代码还都以一群一批的,胸闷,怎么做?

说起这一个主题材料在此之前呢,大家先说一下yii中先关的老大管理类,当然,有非常多哈。比方上边常见的一对,别的的和睦去发现

yiiwebBadRequestHttpException
yiiwebForbiddenHttpException
yiiwebNotFoundHttpException
yiiwebServerErrorHttpException
yiiwebUnauthorizedHttpException
yiiwebTooManyRequestsHttpException

实际付出中各位要专长去采纳这一个类去捕获卓殊,抛出万分。说远了哈,大家回去入眼,来讲怎么样自定义接口非常响应也许叫自定义统一的多寡格式,比方向下边这种布局,统一响应顾客端的格式规范。

'response' => [
 'class' => 'yiiwebResponse',
 'on beforeSend' => function ($event) {
  $response = $event->sender;
  $response->data = [
   'code' => $response->getStatusCode(),
   'data' => $response->data,
   'message' => $response->statusText
  ];
  $response->format = yiiwebResponse::FORMAT_JSON;
 },
],

协调了那么多,本文将在终结了,刚初叶接触的同室也是有部分蒙,不要蒙,慢慢消食,先掌握这么个意思,掌握下restful api接口在全方位进程中是怎么用token授权的就好。那样真的实际行使的时候,你也能一举三反!

以上正是本文的全体内容,希望对我们的就学抱有扶助,也期望我们多多扶助脚本之家。

你恐怕感兴趣的稿子:

  • 完善解读PHP的Yii框架中的日志作用
  • YII Framework框架教程之日志用法详解
  • PHP的Yii框架的常用日志操作计算
  • 详解PHP的Yii框架中国和东瀛记的有关安排及利用
  • yii2项目实战之restful api授权验证详解
  • Yii2设置暗中认可调节器的三种格局
  • Yii2配置Nginx伪静态的艺术
  • Yii2实现自定义独立验证器的情势
  • Yii2数据库操作常用方法小结
  • Yii第22中学增多全局函数的主意深入分析
  • Yii2框架中国和日本记的行使办法解析

本文由星彩网app下载发布于计算机编程,转载请注明出处:授权验证详解,Yii框架分页完结格局详解

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。