Yii2.0 RESTful API 认证教程
认证介绍
和Web应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权状态可能没通过 sessions 或 cookies 维护, 常用的做法是每个请求都发送一个秘密的 access token 来认证用户, 由于 access token 可以唯一识别和认证用户,API 请求应通过 HTTPS 来防止man-in-the-middle (MitM) 中间人攻击.
认证方式
- HTTP 基本认证 :access token 当作用户名发送,应用在access token可安全存在API使用端的场景, 例如,API使用端是运行在一台服务器上的程序。
- 请求参数:
access token当作API URL请求参数发送,例如https://example.com/users?access-token=xxxxxxxx, 由于大多数服务器都会保存请求参数到日志, 这种方式应主要用于JSONP请求,因为它不能使用HTTP头来发送access token - OAuth 2 : 使用者从认证服务器上获取基于
OAuth2协议的access token, 然后通过HTTP Bearer Tokens发送到API服务器。
上方进行简单介绍,内容来自 Yii Framework 2.0 权威指南
实现步骤
我们都知道 Yii2.0 默认的认证类都是 User,前后台都是共用一个认证类,因此我们要把API 认证类 单独分离出来,达到前、后、API都分离,
继上一章:(这里暂时使用默认User数据表,正式环境请分离不同的数据表来进行认证)
准备条件
继上篇的 User 数据表,我们还需要增加一 个access_token 的字段,
- 直接在你的数据库中新增
access_token字段。 - 使用数据迁移的方式
进入项目根目录打开控制台输入以下命令:
php yii migrate/create add_access_token_to_user
打开 你的项目目录/console/migrations/m180704_054630_add_access_token_to_user.php 修改如下内容:
public function safeUp()
{
$this->addColumn('user', 'access_token', $this->string());
}
public function safeDown()
{
$this->dropColumn('user', 'access_token');
}
执行迁移命令
php yii migrate
配置
打开 api\config\main.php
配置 user 应用组件:
* 设置 `identityClass` 属性为哪个认证类
* 设置 `enableSession` 属性为 `false`
* 设置 `enableAutoLogin` 属性为 `true`
将 session 组件注释掉,或删掉
'user' => [
'identityClass' => 'api\models\User',
'enableAutoLogin' => true,
'enableSession'=>false,
//'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
],
//'session' => [ // this is the name of the session cookie used for login on the backend
// 'name' => 'advanced-backend',
// ],
编写 api\models\User.php 实现认证类,继承 IdentityInterface
将 common\models\User 类拷贝到 api\models\目录下,修改命名空间为api\models
<?php
namespace api\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
...
class User extends ActiveRecord implements IdentityInterface
{
...
...
}
将 common\models\LoginForm.php 类拷贝到api\models\目录下,修改命名空间,并重写login方法:
<?php
namespace api\models;
use Yii;
use yii\base\Model;
...
...
public function login()
{
if ($this->validate()) {
$access_token=$this->_user->generateAccessToken();
$this->_user->save();
return $access_token;
} else {
return false;
}
}
上方代码给User模型添加了一个generateAccessToken()方法,因此我们到api\models\User.php中添加此方法
namespace api\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
...
...
class User extends ActiveRecord implements IdentityInterface
{
...
...
/**
* 生成accessToken字符串
* @return string
* @throws \yii\base\Exception
*/
public function generateAccessToken()
{
$this->access_token=Yii::$app->security->generateRandomString();
return $this->access_token;
}
}
接下来打开 之前的User 控制器编写登录方法
use api\models\LoginForm;
...
... //省略一些代码
/**
* 登陆
* @return array
* @throws \yii\base\Exception
* @throws \yii\base\InvalidConfigException
*/
public function actionLogin()
{
$model = new LoginForm();
if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->login()) {
return [
'access_token' => $model->login(),
];
} else {
return $model->getFirstErrors();
}
}
...
最后新增一条URL规则
打开 api\config\main.php 修改 components属性,添加下列代码:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'user',
'extraPatterns'=>[
'POST login'=>'login',
],
],
],
]
使用一个调试工具来进行测试 http://youdomain/users/login 记住是POST 请求发送,假如用POSTMAN有问题的话指定一下 Content-Type:application/x-www-form-urlencoded。
ok,不出意外的话,相信你已经可以收到一个access_token了,接下来就是如何使用这个token,如何维持认证状态,达到不携带这个token将无法访问,返回401
维持认证状态
实现认证只需两步:
- 在你的
REST控制器类中配置authenticator行为来指定使用哪种认证方式 - 在你的 user identity class 类中实现 yiiwebIdentityInterface::findIdentityByAccessToken()-detail) 方法.
接下来我们围绕这两步来实现:
添加一个REST控制器
- 因我这里暂未设计其他数据表 所以我们暂且还使用
User数据表吧
- 在
api\controllers\新加一个控制器 命名为ArticleController并继承yii\rest\ActiveController,配置认证方式代码:代码如下:
<?php
namespace api\controllers;
use yii\rest\ActiveController;
use Yii;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
class ArticleController extends ActiveController
{
public $modelClass = 'api\models\User';
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBasicAuth::className(),
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
];
return $behaviors;
}
}
注意:这个控制器并非真正的Article,实则还是User
- 实现
findIdentityByAccessToken()方法:
打开 api\models\User.php 重写 findIdentityByAccessToken() 方法
...
...
class User extends ActiveRecord implements IdentityInterface
{
...
...
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
...
}
- 为刚才新加的控制器添加路由规则(ps:好像多了一步......)
修改 api\config\main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'user',
'extraPatterns'=>[
'GET send-email'=>'send-email'
'POST login'=>'login',
],
],
['class' => 'yii\rest\UrlRule',
'controller' => 'article',
'extraPatterns'=>[
],
],
],
]
接下来访问一下你的域名 http://youdomain/articles,不携带任何参数是不是返回 401了?
ok,这里介绍两种访问方式,一种是URL访问,另一种是通过header 来进行携带
- http://youdomain/articles?acc...
- 传递
header头信息
Authorization:Bearer y3XWtwWaxqCEBDoE-qzZk0bCp3UKO920
注意 Bearer 和你的token中间是有 一个空格的,很多同学在这个上面碰了很多次
好啦,基于YII2.0 RESTful 认证就此结束了,
更过完整的功能 请移步官方文档
授权验证
另外还有速率验证,就自行发觉吧
另外,如果看不懂,或者写的不好,请移步 魏曦 老师的视频教程,本人所有内容都是跟随 魏曦老师 学的
魏曦教你学
写完认证发现我们的接口返回的数据不是很直观,现实生活中通常也不是这样子的,我们可能会返回一些特定的格式
自定义响应内容
打开 api\config\main.php 在 components数组里面添加如下内容分
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
$response = $event->sender;
$response->data = [
'success' => $response->isSuccessful,
'code' => $response->getStatusCode(),
'message' => $response->statusText,
'data' => $response->data,
];
$response->statusCode = 200;
},
],
这里的状态码统一设为 200 ,具体的可另行配置,假如登陆操作 密码错误或者其他,我们可以在控制器中这样使用:
$response = Yii::$app->response;
$response->setStatusCode(422);
return [
'errmsg' => '用户名或密码错误!'
];
水平有限,难免有纰漏,请不吝赐教,在下会感激不尽
原文地址:https://segmentfault.com/a/1190000016368603
Yii2.0 RESTful API 认证教程的更多相关文章
- Yii2.0 RESTful API 之速率限制
Yii2.0 RESTFul API 之速率限制 什么是速率限制? 权威指南翻译过来为限流,为防止滥用,你应该考虑对您的 API 限流. 例如,您可以限制每个用户 10 分钟内最多调用 API 100 ...
- Yii2.0 RESTful API 基础配置教程
创建api应用 通过拷贝原有的应用,重命名得到新的应用 安装完 Composer,运行下面的命令来安装 Composer Asset 插件: php composer.phar global req ...
- Yii2框架RESTful API教程(二) - 格式化响应,授权认证和速率限制
之前写过一篇Yii2框架RESTful API教程(一) - 快速入门,今天接着来探究一下Yii2 RESTful的格式化响应,授权认证和速率限制三个部分 一.目录结构 先列出需要改动的文件.目录如下 ...
- Yii2框架RESTful API教程(一) - 快速入门
前不久做一个项目,是用Yii2框架写一套RESTful风格的API,就去查了下<Yii 2.0 权威指南 >,发现上面写得比较简略.所以就在这里写一篇教程贴,希望帮助刚接触Yii2框架RE ...
- spring jwt springboot RESTful API认证方式
RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authentication)和授权(Authorization)过程,保证API的安全性. Authenticatio ...
- Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(一)
标题 Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(一) 技术 Spring Boot 2.Spring Security 5.JWT 运行环境 ...
- .Netcore 2.0 Ocelot Api网关教程(2)- 路由
.Netcore 2.0 Ocelot Api网关教程(1) 路由介绍 上一篇文章搭建了一个简单的Api网关,可以实现简单的Api路由,本文介绍一下路由,即配置文件中ReRoutes,ReRoutes ...
- Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二)
Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二) 摘要 上一篇https://javaymw.com/post/59我们已经实现了基本的登录和t ...
- Yii2框架RESTful API教程
前不久做一个项目,是用Yii2框架写一套RESTful风格的API,就去查了下<Yii 2.0 权威指南 >,发现上面写得比较简略.所以就在这里写一篇教程贴,希望帮助刚接触Yii2框架RE ...
随机推荐
- JAVA基础实例(一)
1写一个方法,用一个for循环打印九九乘法表 /** *一个for循环打印九九乘法表 */ public void nineNineMultiTable() { for (int i = 1,j = ...
- Spark部分:几个重要的端口汇总
50070:HDFSwebUI的端口号 8485:journalnode默认的端口号 9000:非高可用访问数rpc端口 8020:高可用访问数据rpc 8088:yarn的webUI的端口号 808 ...
- 《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析
在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...
- Swagger框架学习分享
Swagger框架学习分享 转至元数据结尾 Created and last modified by 刘新宇 大约1分钟曾经 pageId=162045803#page-metadata-start& ...
- Linux学习之设置联网,关闭防火墙,关闭selinux
桥接模式,给一台物理机,有自己独立的IP. boot分区,引导分区,系统启动,内核文件. swap分区,内存扩展分区.1.5或2倍.内存不够的时候,会写入其中.正常给8G或者16G就够了.不需要非要1 ...
- 神经网络中的激活函数——加入一些非线性的激活函数,整个网络中就引入了非线性部分,sigmoid 和 tanh作为激活函数的话,一定要注意一定要对 input 进行归一话,但是 ReLU 并不需要输入归一化
1 什么是激活函数? 激活函数,并不是去激活什么,而是指如何把“激活的神经元的特征”通过函数把特征保留并映射出来(保留特征,去除一些数据中是的冗余),这是神经网络能解决非线性问题关键. 目前知道的激活 ...
- Redis List 命令技巧
1.实现栈的功能(先进后出) lpush + lpop = stack > lpush mylist (integer) > lpop mylist " > lpop my ...
- linux编译安装ccache3.2.4
1.下载ccache3.2.4安装包 #cd /opt #wget http://samba.org/ftp/ccache/ccache-3.2.4.tar.gz 2.解压 #.tar.gz 3.创建 ...
- Prism学习(1)---前期准备
本文摘取自Gene's Blog的博客园文章,版权归Gene's Blog,仅供个人学习参考.转载请标明原作者Gene's Blog. 在学习Prism框架之前,我预先写了一个非常简单的计算器解决方案 ...
- 修复wordpress插件编辑器漏洞
具体方法,将下面的代码添加到您的配置文件 wp-config.php中: define( 'DISALLOW_FILE_EDIT', true ); 以此关闭插件编辑器功能,一切就这么简单,漏洞也就不 ...