详解用 MiniFramework 框架实现对 GET 或 POST 请求参数进行签名校验的方法

在一些特殊场景下,我们可能希望对于 GET 或 POST 进入到接口的数据进行签名和有效期的校验,例如 APP 请求后端接口的场景,我们通常需要考虑两个问题:

问题1:如何避免攻击者在捕获到接口请求后,自行构造请求参数,向接口发送请求,而不通过 APP 的正常界面进行操作。

问题2:在接口请求不可避免能被捕获的情况下,如何确保每一次请求能够过期,不被反复的利用,例如投票刷票的问题。

基于上面两个问题,我们在设计接口时,就需要通过给请求参数进行签名的方式来对数据来源和有效期进行校验。下面将以 MiniFramework 框架为例,演示如何通过 MiniFramework 框架来实现对请求参数进行签名和签名校验的方法。

首先,我们创建一个名为 Index 的控制器,并在控制器中创建名为 sign 和 verifysign 两个动作方法,分别用于生成签名,和校验签名,具体代码如下:

<?php
// 声明控制器命名空间
namespace App\Controller;

// 加载动作类
use Mini\Base\Action;

// 加载签名类
use Mini\Security\Sign;


class Index extends Action
{
    /**
     * 生成签名
     */
    function signAction()
    {
        // 待签名的数据
        $data = [

            // 假设我们要通过GET方式传递参数info=MiniFramework
            'info' => 'MiniFramework',

            // signTime为当前时间戳,且必须随数据一起进行签名
            'signTime' => time()
        ];

        // 实例化签名类
        $signObj = new Sign();

        // 指定用 sha1 来进行加密(默认为:md5)
        $signObj->setEncryptType('sha1');

        // 获得一个签名
        $sign = $signObj->sign($data);

        // 签名随其他数据一起通过GET传递
        $data['sign'] = $sign;
        dump($data);

        // 构造一个GET请求URL
        $dataStr = arrayToUrlParams($data);
        $url = $this->view->baseUrl() . '/index/verifysign?' . $dataStr;
        echo '<a href="' . $url . '" target="_blank">点击这里跳转到签名验证页</a>';

        die();
    }

    /**
     * 验证签名
     */
    function verifysignAction()
    {
        // 实例化
        $signObj = new Sign();

        // 验证时需要使用相同的加密方式
        $signObj->setEncryptType('sha1');

        // 设定签名过期时间为30秒(默认为:300秒)
        $signObj->setExpireTime(30);

        // 获得签名校验结果(传入参数get代表对GET请求进行签名校验)
        $res = $signObj->verifySign('get');

        if ($res === true) {
            echo '签名有效';
        } else {
            echo '签名无效';
        }

        die();
    }
}

 

完成上述代码编写后,我们可以通过浏览器访问这个控制器的 sign 动作方法,生成签名并构造一个跳转链接,通过跳转链接进入 verifysign 动作方法完成对请求的签名校验。

我们从代码中可以看到签名使用的是 sha1 加密算法,生成签名和校验签名要使用相关的加密算法,否则将无法正确进行校验。

签名的有效期在 verifysign 动作方法中通过 setExpireTime() 设定为30秒,那么从签名被生成开始,有效期为30秒,过期后的签名将无法通过校验。

上述针对签名校验的特性在 MiniFramework 的 2.4.0 版本中加入,示例代码可以在项目的 Example 控制器中找到。

获取 MiniFramework 源代码请移步至码云Gitee仓库:https://gitee.com/jasonwei/miniframework

 

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3m34f5dknekg8

MiniFramework 2.9.0 已经发布,超轻量级的 PHP 框架

MiniFramework 2.9.0 已经发布,超轻量级的 PHP 框架

此版本更新内容包括:

版本变化

  • 新增 Mini\Base\Header 类,用于处理 Request 和 Response 的 Header 信息。
  • 新增 Mini\Base\Response 类,用于响应客户端,控制请求结果的输出。
  • 新增 Mini\Base\App::setAction () 方法,用于设置动作。
  • 新增 Mini\Base\App::setController () 方法,用于设置控制器。
  • 新增 Mini\Base\Action::forward () 替代原 _forward () 方法,旧方法暂时保留,新旧两个方法功能完全一致。
  • 新增 Mini\Security\Sign 类的 setEncryptType () 方法,用于指定加密方式。
  • 改进 Controller 和 Action 的设置由 Mini\Base\App 类负责处理。
  • 改进在部分核心类库中用 Mini\Base\Response 替代 Mini\Base\Http 以规范响应输出。
  • 改进并优化框架异常报错的特性。
  • 修复 Action 中使用 $this->_forward () 跳转相同的 Action 时出现死循环的 Bug。
  • 修复 Mini\Base\Http 在被继承的场景中可能出现的实例获取 Bug。
  • 修复全局函数 isTimestamp () 校验时间戳的 Bug。

升级说明

  • 兼容 PHP 最低版本为 7.2.0,PHP 8.0.0 已测试可正常运行。
  • 当前版本向前兼容至 2.4.0 版本,使用 2.4.0 及后续版本的开发者可直接升级至 2.9.0 版本。
  • 文档已同步更新,地址:http://www.miniframework.com/docv2/guide/

详情查看:https://gitee.com/jasonwei/miniframework/releases/2.9.0

采用 MiniFramework 框架开发的 MiniAdmin 完成了 1.0 版

长久以来一直对于 MiniFramework 没有一个相对完整并且成体系的项目而发愁,仅仅有框架的源代和文档码摆在那里,似乎还是不足以让朋友们能够上手 Miniframework 框架。

为此,从去年年底开始,见缝插针的利用业余时间,开始着手用 MiniFramework 来写一个后台模板项目,项目的名字叫 MiniAdmin,源代码在 https://github.com/jasonweicn/miniadmin

在 MiniAdmin 中,我尽可能多的利用 MiniFramework 框架的各种特性,来实现后台模板的各种功能场景,以便让朋友们通过 MiniAdmin 这个项目,可以深入了解 MiniFramework 框架的一些特性,得以通过这个项目学习掌握 MiniFramework 框架。

尽管 MiniAdmin 还非常简单,但我会努力去完善她,加入更丰富的功能。同时,也会通过这个项目,来促进 MiniFramework 框架更好的发展下去。

PHP 开源框架 MiniFramework 入驻码云

MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。MiniFramework 能够帮助开发者用最小的学习成本快速构建 Web 应用,在满足开发者最基础的分层开发、数据库和缓存访问等少量功能基础上,做到尽可能精简,以帮助您的应用基于框架高效运行。

近日,MiniFramework 已经入驻码云,在未来的跟新迭代过程中,框架源代码将同时推送到 GitHub 和码云的代码仓库中,两个平台上代码保持同步。

GitHub地址:https://github.com/jasonweicn/miniframework
码云地址:https://gitee.com/jasonwei/miniframework

详解用 MiniFramework 计算程序运行时间的方法

我们在项目调优过程中,通常会对代码的运行时间进行统计,以便了解程序运行的性能和效率,这些统计结果将作为代码优化时的重要指标,帮助开发者有针对性的进行调优工作。

MiniFramework 在 1.3.0 版本中,新增了 Debug 类,其中包含有时间统计功能的若干方法,可以非常便捷地帮助开发者实现上述统计需求,下面我们来通过示例代码介绍具体实现方法。

首先,假设我们有一个名为 Index 的 Controller,并且其中包含有一个名为 index 的 Action(MiniFramework下载包中已经包含),我们将代码写在这个 Action 中,如下:

阅读更多

PHP 开源框架 MiniFramework 发布 1.4.0 版

MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。MiniFramework 能够帮助开发者用最小的学习成本快速构建 Web 应用,在满足开发者最基础的分层开发、数据库和缓存访问等少量功能基础上,做到尽可能精简,以帮助您的应用基于框架高效运行。

MiniFramework于2018年9月13日发布1.4.0版本,变化有:

* 新增Log类,用于以日志的形式记录代码运行报错和开发者自定义的调试信息。
* 新增常量LOG_ON,用于控制日志功能的开启和关闭(生产环境建议关闭)。
* 新增常量LOG_LEVEL,用于定义可被写入日志的错误等级。
* 新增常量LOG_PATH,用于定义日志存储路径。
* 新增Debug类的varType方法,用于判断变量类型。
* 改进优化异常控制相关功能。

阅读更多

用 MiniFramework 实现文件上传功能

MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。

在 MiniFramework 最新的版本中,提供了上传文件的特性,下面我们来演示一下实现过程。

首先,新建一个名为 Upload 的 Controller,并在其中新建一个名为 index 的 Action,代码如下:

<?php
namespace App\Controller;

use Mini\Upload;

class Upload extends Action
{
    function indexAction()
    {
        if (! empty($_FILES)) {
            
            // 实例化 Upload 类
            $upload = new Upload();
            
            $res = $upload->save($_FILES['f']);
            if (! $res) {
                $errmsg = $upload->getErrorMsg();
                echo $errmsg;
            } else {
                dump($res);
            }
        }
        
        $this->view->display();
    }
}

上边的代码中,通过 use Mini\Upload; 引入了 MiniFramework 框架所提供的一个用于文件上传的类库。

在实例化 Upload 类后,通过调用 save 方法,并将 PHP 的 $_FILES 传入,来实现上传文件的保存。

在调用 save 方法后,若文件保存失败,可以通过 getErrorMsg 方法来获取错误信息。

如果文件保存成功,那么 save 方法会返回一个数组,其中包含有文件保存的路径和文件名,上边的示例代码中使用了 MiniFramework 内置的全局函数 dump() 来输出 save 所返回的数组。

另外,在实例化 Upload 类时,可传入一个数组类型的参数,对文件保存路径、大小和类型进行设定,例如:

// 配置数组
$config = array(

    // 文件保存的根目录
    'rootPath'  => PUBLIC_PATH . '/uploads',

    // 文件的大小限制(单位:Byte)
    'maxPath'   => 512000,

    // 允许的类型
    'allowType' => 'bmp,gif,jpg,jpeg,png'

);

// 实例化 Upload 类时,将配置数组作为参数传入
$upload = new Upload($config);

上边的代码中,常量 PUBLIC_PATH 是 MiniFramework 内置用于定义站点根目录所对应的路径,默认对应的是 Public 目录所在的路径

接下来创建视图,在 View 目录中创建一个名为 upload 的目录,将视图文件保存到 View/upload/index.php,代码如下:

<h1>Upload</h1>
<form method="post" enctype="multipart/form-data">
  <input type="file" name="f" >
  <input type="submit" value="upload" /></p>
</form>

完成上述步骤后,便可以访问类似下面的地址来测试了
http://你的域名/index.php?c=upload&a=index

如果你的站点开启了伪静态,那么访问地址可以是下面这样:
http://你的域名/upload/index

上边的 URL 中,最后的 index 可以省略,例如:
http://你的域名/upload

阳光部落原创,更多内容请访问http://www.sunbloger.com/

PHP 开源框架 MiniFramework 发布 1.1.0 版

MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。MiniFramework 能够帮助开发者用最小的学习成本快速构建 Web 应用,在满足开发者最基础的分层开发、数据库和缓存访问等少量功能基础上,做到尽可能精简,以帮助您的应用基于框架高效运行。

MiniFramework于2018年6月10日发布1.1.0版本,变化有:

* 新增Captcha类,用于生成和校验图片验证码
* 新增Registry类的unset方法,用于删除已注册的变量
* 新增全局函数browserDownload(),用于让浏览器下载文件
* 在App目录中,新增名为Example的控制器,其中包含部分功能的示例代码

MiniFramework 1.1.0 版本下载地址
zip格式:https://github.com/jasonweicn/MiniFramework/archive/1.1.0.zip
tar.gz格式:https://github.com/jasonweicn/MiniFramework/archive/1.1.0.tar.gz

MiniFramework 快速入门文档
地址:http://www.miniframework.com/docv1/guide/

近期版本更新主要变化回顾:

1.0.13

* 改进Db_Mysql中的execTrans方法
* 改进渲染特性
* 新增全局函数isImage(),用于判断文件是否为图像格式
* 新增全局函数getStringLen(),用于获取字符串长度(支持UTF8编码的汉字)

1.0.12

* 新增Session类,用于读写会话数据

1.0.11

* 改进转换伪静态地址分隔符的机制
* 优化路由处理伪静态时的性能
* 优化部分核心类的属性
* 优化框架内存占用

MiniFramework新增了图片验证码输出和校验功能

今天为 MiniFramework 新增了一个名为 Captcha 的类,用于图片验证码的输出和校验。

具体用法如下:

用 MiniFramework 新建一个名为 Example 的控制器,例如:

<?php
namespace App\Controller;

use Mini\Action;
use Mini\Captcha;

/**
 * Example
 */
class Example extends Action
{
    function captchaAction()
    {
        if (!empty($_POST['code'])) {
            $captcha = new Captcha();
            $res = $captcha->check($_POST['code']);
            if ($res) {
                $this->view->assign('info', 'success');
            } else {
                $this->view->assign('info', 'fail');
            }
            $this->view->assign('code', $_POST['code']);
        }
        
        $this->view->display();
    }
    
    function getcaptchaAction()
    {
        $captcha = new Captcha();
        $captcha->create();
    }
}

 

同时创建视图,代码如下:

<?php if (isset($this->code)) echo '<p>input code: ' . $this->code . '</p>';?>
<?php if (isset($this->info)) echo '<p>check result: ' . $this->info . '</p>';?>
<img src="getcaptcha" onclick="this.src='getcaptcha?t='+Math.random()" />
<form method="post" action="captcha">
  <p>code:<input type="text" name="code" value="" />
  <input type="submit" value="check" /></p>
</form>

 

创建完成后,访问 http://你的域名/example/captcha 即可看到效果。

上边的代码已经包含在 MiniFramework 位于 GitHub 的 master 主线上。

GitHub源代码地址:https://github.com/jasonweicn/MiniFramework

用 MiniFramework 快速构建 REST 风格的 API 接口

MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。

通过 MiniFramework 内置的 REST 接口功能,我们可以很轻松的快速构建起基于 REST 风格的 API 接口,特别是在开发 iOS 和 Android 手机客户端应用时,服务器端的 API 接口是否灵活高效,直接影响着手机应用的体验。

下面介绍一下如何使用 MiniFramework 开发 REST 风格的 API 接口。

第一步,我们下载最新 MiniFramework 1.0.2 版本

下载地址是:https://github.com/jasonweicn/MiniFramework/archive/1.0.2.zip

下载并解压缩后,会看到里面有 App 和 MiniFramework 两个目录,App 目录是一个附带的应用 demo,MiniFramework 目录是框架核心文件。

第二步,我们在 Apache 或 Nginx 中新建一个站点,并将站点的根目录指向 App/Public 这个目录。

设置好站点根目录后,我们可以测试一下,用浏览器访问下面的 URL 地址:

http://你的域名/index.php?c=index&a=index

如果可以显示“Hello World!”,说明站点已经部署成功了。

第三步,为了优化访问 URL 访问的便捷性,我们要给站点设置伪静态规则。

如果你用的是 Apache,那么附带的应用 demo 中已经提供了 .htaccess 文件,不需要额外的设置了。

如果你用的是 Nginx,那么需要在 nginx.conf 中,向对应站点的 server{} 段中,增加下面的代码:

location / {
    index  index.html index.php;
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php last;
    }
}

 

保存后,别忘记重启 Nginx 让配置生效。

经过上述配置后,用浏览器访问下面的 URL 地址:

http://你的域名/index/index

如果可以显示“Hello World!”,那就说明伪静态也配置成功了。

第四步,创建 API 程序

找到 App/Api 目录,这里是存放 API 接口的地方,在里面已经附带了一个名为 Version.php 的 demo,你可以参考这个文件的代码,编写自己的 API,比如我们创建一个名为 User.php,里面放置 get、post、put 和 delete 四个方法,分别对应 REST 中的 GET、POST、PUT 和 DELETE 请求。代码如下:

<?php
//首先要声明当前文件的命名空间为 App\Api
namespace App\Api;
 
//还要引入 Mini\Rest
use Mini\Rest;
 
class User extends Rest //必须要继承Rest类
{
    /**
     * 初始化
     */
    function _init()
    {
        //do something...
    }
    
    /**
     * GET
     */
    function get()
    {
        //我们临时构建一个用户列表数组,在你的业务代码中或许应该通过模型从数据库中读取
        $userlist = array(
            array('id'=>1, 'name'=>'user1'),
            array('id'=>2, 'name'=>'user2'),
            array('id'=>2, 'name'=>'user3')
        );
        
        //将$userlist通过responseJson()方法输出为JSON
        $this->responseJson(200, 'success', $userlist);
    }
    
    /**
     * POST
     */
    function post()
    {
        //获取POST参数
        $params = $this->params->getParams();
        
        //do something...
    }
    
    /**
     * PUT
     */
    function put()
    {
        //获取PUT参数(POST和PUT参数均可通过此方法获得)
        $params = $this->params->getParams();
        
        //do something...
    }
    
    /**
     * DELETE
     */
    function delete()
    {
        //返回HTTP状态码403(在REST中表示对于拒绝访问)
        $this->responseJson(403);
    }
}

 

创建好上边的 API 后,我们可以测试一下,用浏览器访问下面的 URL 地址:

http://你的域名/api/user

此时的访问请求属于 GET 方式,MiniFramework 会将这个请求映射到我们刚刚创建的 User 类的 get() 方法上,如果一切正常,我们会看到浏览器中显示如下内容:

{"code":200,"msg":"success","data":[{"id":1,"name":"user1"},{"id":2,"name":"user2"},{"id":2,"name":"user3"}]}

 

上边显示的内容就是通过 responseJson() 方法输出的 JSON 字符串了,其中 code 代表这次请求服务器返回的状态代码,msg 是返回的说明,data 里面就是这次请求发出后,服务器返回给客户端的数据了。

我们可以看到,上边 User 类的代码中,在最开始要通过 namespace 来声明当前文件的命名空间,在 MiniFramework 中,默认情况下 API 接口的命名空间统一为 App/Api。

再往下还要通过 use 引入 Mini\Rest,这个是 MiniFramework 的核心类之一,我们创建的 API 接口的 class 必须要继承 Rest。

再往下就是 REST 中经典的 get、post、put 和 delete 四个方法,对于客户端请求类型的映射问题,MiniFramework 会自动帮我们处理好,我们只要专注写好业务逻辑就可以了。

阳光部落原创,更多内容请访问 http://www.sunbloger.com/