yii2项目实战之restful,授权验证

作者:计算机知识

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

哪些是restful风格的api呢?大家前边有写过大篇的小说来介绍其定义以及基本操作。

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

前言

既然如此写过了,这明日是要说点什么吗?

既然如此写过了,那明天是要说点什么啊?

既然写过了,那明天是要说点什么啊?

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

那篇小说首要针对实际场景中api的配置来写。

这篇小说主要针对实际场景中api的计划来写。

这篇小说主要针对实际场景中api的配置来写。

既然如此写过了,那后天是要说点什么吗?

咱俩前几日就来大大的侃侃那个年api境遇的授权验证难点!独家干活,若是看完全数收益,记得不要遗忘给本人点赞哦。

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

咱俩前些天就来大大的侃侃那么些年api遭受的授权验证难点!独家干活,假若看完全部受益,记得不要忘记给自己点赞哦。

那篇小说首要针对实际场景中api的配置来写。

政工解析

作业深入分析

业务深入分析

大家今天就来大大的侃侃那个年api碰到的授权验证难点!独家干活,假若看完全部受益,记得不要遗忘给自个儿点赞哦。

笔者们先来询问一下方方面面逻辑

大家先来打探一下全体逻辑

咱俩先来通晓一下整整逻辑

政工解析

1.用户在客户端填写登陆表单
2.用户提交表单,客户端诉求登陆接口login
3.服务端校验用户的帐号密码,并重临一个立见成效的token给客户端
4.客户端获得用户的token,将之存款和储蓄在客户端例如cookie中
5.客户端引导token访谈供给校验的接口举例获取用户个人新闻接口
6.服务端校验token的卓有功用,校验通过,反正重回客户端须要的新闻,校验失利,需求用户重新登陆

1.用户在客户端填写登入表单
2.用户提交表单,客户端诉求登入接口login
3.服务端校验用户的帐号密码,并赶回三个有效的token给客户端
yii2项目实战之restful,授权验证。4.客户端得到用户的token,将之存款和储蓄在客户端举例cookie中
5.客户端引导token访谈须要校验的接口比如获取用户个人音信接口
6.劳务端校验token的实惠,校验通过,反正重回客户端需求的音讯,校验战败,需求用户重新登陆

  1. 用户在客户端填写登入表单
  2. 用户提交表单,客户端要求登入接口login
  3. 服务端校验用户的帐号密码,并回到多个得力的token给客户端
  4. 客户端获得用户的token,将之存款和储蓄在客户端举例cookie中
  5. 客户端带领token访问供给校验的接口比方获取用户个人音讯接口
  6. 劳务端校验token的有用,校验通过,反正重回客户端需求的音讯,校验战败,必要用户重新登入

咱俩先来驾驭一下方方面面逻辑

本文大家以用户登入,获取用户的个人音信为例举行详细的总体版表达。

正文大家以用户登陆,获取用户的个人新闻为例举行详细的完全版表达。

正文大家以用户登入,获取用户的个人消息为例进行详细的欧洲经济共同体版表明。

  • 用户在客户端填写登陆表单
  • 用户提交表单,客户端诉求登录接口login
  • 服务端校验用户的帐号密码,并回到多少个使得的token给客户端
  • 客户端得到用户的token,将之存款和储蓄在客户端比如cookie中
  • 客户端教导token访问须要校验的接口譬喻获取用户个人音讯接口
  • 劳动端校验token的可行,校验通过,反正重回客户端须求的新闻,校验退步,供给用户重新登入

上述,就是大家本篇小说要促成的主要。先别激动,也别紧张,剖析好了之后,细节部分大家再望文生义走下来。

上述,就是我们本篇小说要实现的要害。先别激动,也别恐慌,深入分析好了今后,细节部分大家再切实地专业走下来。

上述,就是我们本篇文章要兑现的首要性。先别激动,也别恐慌,深入分析好明白后,细节部分我们再安分守己走下来。

本文大家以用户登入,获取用户的个人音信为例实行详尽的总体版表明。
以上,就是大家本篇小说要兑现的第一。先别激动,也别恐慌,剖析好了将来,细节部分大家再足履实地走下来。

忧盛危明干活

预备干活

有备无患专门的学问

预备工作

1.您应有有三个api应用.
2.对于客户端,大家希图使用postman进行模拟,假诺你的google浏览器还尚未安装postman,请先活动下载
3.要测量试验的用户表须求有一个api_token的字段,未有的请先自行增加,并保险该字段充分长度
4.api应用开启了路由美化,并先配置post类型的login操作和get类型的signup-test操作
5.关闭了user组件的session会话

1.你应当有贰个api应用.
2.对此客户端,我们企图接纳postman举行效仿,假若您的google浏览器还并未有设置postman,请先活动下载
3.要测量检验的用户表要求有三个api_token的字段,未有的请先自行增添,并保管该字段丰富长度
4.api应用开启了路由美化,并先配置post类型的login操作和get类型的signup-test操作
5.关闭了user组件的session会话

  1. 您应该有贰个api应用,假设你还不曾,请先活动这里→_→Restful api基础
  2. 对此客户端,大家计划选用postman进行效仿,如若您的google浏览器还一向不设置postman,请先活动下载
  3. 要测量试验的用户表需求有三个api_token的字段,未有的请先自行加多,并保管该字段丰富长度
  4. api应用开启了路由美化,并先配置post类型的login操作和get类型的signup-test操作
  5. 关闭了user组件的session会话
  • 您应该有三个api应用,若是你还尚未,请先活动这里→_→Restful api基础
  • 对此客户端,大家企图利用postman实行效仿,假设你的google浏览器还未有设置postman,请先活动下载
  • 要测量检验的用户表需求有几个api_token的字段,未有的请先自行加多,并确定保障该字段充分长度
  • api应用开启了路由美化,并先配置post类型的login操作和get类型的signup-test操作
  • 关闭了user组件的session会话

关于地点计划干活的第4点和第5点,大家贴一下代码方便领悟

关于地点盘算干活的第4点和第5点,大家贴一下代码方便领悟

有关地方准备专业的第4点和第5点,我们贴一下代码方便清楚

至于地方策画职业的第4点和第5点,大家贴一下代码方便清楚

'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',
    ]
   ],
  ]
 ],
 // ......
],

'components'=> [

'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',
                ]
            ],
        ]
    ],
    // ......
],
'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',
  ]
  ],
 ]
 ],
 // ......
],

signup-test操作大家前面增多测量检验用户,为记名操作提供有益。其余品种的操作前面看必要再做加多。

 'user'=> [ 

signup-test操作大家后边加多测试用户,为记名操作提供有益。别的项目的操作前面看须求再做加多。

signup-test操作大家后边增多测量检验用户,为记名操作提供有利。其余类型的操作后边看需求再做加多。

认证类的抉择

  'identityClass'=>'commonmodelsUser',

认证类的选取

认证类的挑三拣四

我们在apimodulesv1controllersUserController中设定的model类指向 commonmodelsUser类,为了求证注重这里大家就不独立拿出来重写了,看各位供给,有至关重要的话再单独copy多个User类到apimodels下。

  'enableAutoLogin'=> true,

我们在apimodulesv1controllersUserController中设定的model类指向 commonmodelsUser类,为了证实重点这里我们就不独立拿出去重写了,看各位须要,有要求的话再单独copy三个User类到apimodels下。

我们在apimodulesv1controllersUserController中设定的model类指向 commonmodelsUser类,为了验证注重这里大家就不单独拿出去重写了,看各位要求,有不能缺少的话再单独copy三个User类到apimodels下。

校验用户权限大家以 yiifiltersauthQueryParamAuth 为例

  'enableSession'=> false,

校验用户权限我们以 yiifiltersauthQueryParamAuth 为例

校验用户权限大家以 yiifiltersauthQueryParamAuth 为例

use yiifiltersauthQueryParamAuth;

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

 ],

use yiifiltersauthQueryParamAuth;

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

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

如此一来,那岂不是全数访谈user的操作都急需验证了?那要命,客户端第贰个访谈login操作的时候哪来的token,yiifiltersauthQueryParamAuth对外提供贰个属性,用于过滤无需表明的action。大家将UserController的behaviors方法稍作修改

 'urlManager'=> [

如此一来,那岂不是全部访问user的操作都供给注解了?那极其,客户端第贰个访谈login操作的时候哪来的token,yiifiltersauthQueryParamAuth对外提供叁性格格,用于过滤无需证实的action。大家将UserController的behaviors方法稍作修改

如此一来,那岂不是全体访谈user的操作都急需验证了?那要命,客户端第多个访问login操作的时候哪来的token,yiifiltersauthQueryParamAuth对外提供壹本质量,用于过滤无需表明的action。大家将UserController的behaviors方法稍作修改

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

  'enablePrettyUrl'=> true,

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

那样login操作就无需权限验证就能够访问了。

  'showScriptName'=> false,

如此这般login操作就无需权限验证就可以访谈了。

那样login操作就不需求权限验证就可以访谈了。

累加测验用户

  'enableStrictParsing'=> true,

增添测量检验用户

丰硕测量检验用户

为了幸免让客户端登陆退步,我们先写一个轻巧的艺术,往user表里面插入两条数据,便于接下去的校验。 

  'rules'=> [

 

为了幸免让客户端登陆失利,大家先写四个归纳的点子,往user表里面插入两条数据,便于接下去的校验。

UserController扩充signupTest操作,注意此办法不属于讲明范围之内,我们仅用于方便测验。

   [

为了制止让客户端登入失败,大家先写二个回顾的办法,往user表里面插入两条数据,便于接下去的校验。

UserController扩展signupTest操作,注意此情势不属于批注范围之内,大家仅用于方便测量试验。

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
 ];
}

    'class'=>'yiirestUrlRule',

 

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
 ];
}

如上,大家增多了三个username是111,密码是123456的用户

    'controller'=> ['v1/user'],

UserController增添signupTest操作,注意此措施不属于疏解范围之内,大家仅用于方便测量试验。

如上,大家增加了一个username是111,密码是123456的用户

签到操作

    'extraPatterns'=> [

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
    ];
}

报到操作

万一用户在客户端输入用户名和密码实行登陆,服务端login操作实际很简单,大多数的工作逻辑处理都在apimodelsloginForm上,来先看看login的贯彻

     'POST login'=>'login',

如上,大家增添了二个username是111,密码是123456的用户

借使用户在客户端输入用户名和密码实行登入,服务端login操作实际比不会细小略,大多数的事情逻辑管理都在apimodelsloginForm上,来先看看login的兑现

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;
 }
}

     'GET signup-test'=>'signup-test',

签到操作

use apimodelsLoginForm;

签到成功后这里给客户端再次回到了用户的token,再来看看登入的切切实实逻辑的贯彻

    ]

假使用户在客户端输入用户名和密码进行登陆,服务端login操作实际很简单,大多数的事务逻辑管理都在apimodelsloginForm上,来先看看login的贯彻

/**
 * 登录
 */
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;
 }
}

新建apimodelsLoginForm.PHP

   ],

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;
    }
}

签到成功后这里给客户端再次来到了用户的token,再来看看登入的现实逻辑的贯彻

<?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);
  }
 }
}

  ]

报到成功后这里给客户端重回了用户的token,再来看看登陆的有血有肉逻辑的贯彻

新建apimodelsLoginForm.PHP

大家回过头来看一下,当大家在UserController的login操作中调用LoginForm的login操作后都产生了哪些

 ],

新建apimodelsLoginForm.PHP

<?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);
 }
 }
}

1、调用LoginForm的login方法

 // ......

<?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);
        }
    }
}

笔者们回过头来看一下,当大家在UserController的login操作中调用LoginForm的login操作后都发出了什么

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

],

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

      1、调用LoginForm的login方法

3、rules校验中调用validatePassword方法,对用户名和密码进行校验

signup-test操作我们前面加多测量试验用户,为报到操作提供便利。别的门类的操作前面看须要再做增添。

1、调用LoginForm的login方法

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

本文由bwin必赢发布,转载请注明来源

关键词: 规范