學習thinkphp中api介面資料安全解決方案之sign有效時間處理

徊憶羽菲發表於2021-01-03

學習thinkphp中api介面資料安全解決方案之sign有效時間處理

生成13位時間戳

在Y:\thinkphpwu\application\common\lib 目錄中建立 Time.php 類
在這裡插入圖片描述

<?php

namespace app\common\lib;

class Time
{

    //獲取到13位數的時間戳 13位時間戳是把時間精確到毫秒級,所以兩者是1000倍的關係
    public static function get13TimeStamp()
    {
        //用空格分隔,分別賦值給time1,和time2
        list($time1, $time2) = explode(' ', microtime());
        return $time2 . ceil($time1 * 1000);
    }
}

生成sign簽名


use app\common\lib\Time;



   public function testAes()
    {
        $data = array(
            'name' => 'qipa250',
            'url' => 'www.qipa250.com',
            'time' => Time::get13TimeStamp(),
        );
        echo '生成的簽名是==' . ApiAuth::setSign($data);
    }

設定sign簽名有效期

在這裡插入圖片描述
在thinkphpwu\application\extra 目錄下的app.php 檔案中設定sign簽名有效期

<?php

return [
    'admin_password_pre' => '_qipa250',//後臺管理員密碼加密字尾
    'aeskey' => 'QiPa250',//aes 金鑰,服務端和客戶端保持一致
    'aesiv' => '12345678901234567890123456789012',//aes iv,服務端和客戶端保持一致
    'apptypes' => ['ios', 'android', 'wechat'],
    'api_sign_expire_time' => 10,//sign簽名有效期為10s,
];

校驗sign時間有效期

在這裡插入圖片描述
在Y:\thinkphpwu\application\common\lib 目錄下新建ApiAuth.php類

<?php

namespace app\common\lib;

use app\common\lib\Aes;


class ApiAuth
{

    /*
     * 生成簽名
     */
    public static function setSign($data = [])
    {
        //1 把陣列按照欄位你排序
        ksort($data);
        //2 將陣列更改為拼接字串的格式
        $sign_str = http_build_query($data);
        //3 通過aes加密
        return (new Aes())->encrypt($sign_str);
    }

    //校驗簽名sign
    public static function checkSign($data)
    {
        //解密
        $str = (new Aes())->decrypt($data['sign']);
        if (!$str) {
            return false;
        }
        //將字串你轉成陣列格式
        parse_str($str, $arr);
 
        //校驗sign有效期 由於解析後的日期是13位的,除以1000後得到10位數
        //兩個時間再相減, 超過設定的有效
        if ((time() - ceil($arr['time'] / 1000)) > config('app.api_sign_expire_time')) {
            return false;
        }
        return true;
    }
}

引用簽名驗證類

Y:\thinkphpwu\application\api\controller
在這裡插入圖片描述

在api模組的公共類Common.php中 引用簽名驗證方法

<?php

namespace app\api\controller;

use app\common\lib\ApiAuth;
use app\common\lib\Time;
use think\Controller;

use app\common\lib\exception\ApiException;

use app\common\lib\Aes;

/*
 * api介面模組的公共控制器
 */

class Common extends Controller
{

    public function _initialize()
    {
        $this->checkRequestAuth();     
    }

    //驗證方法
    /*
     * 檢查app每一次提交的資料是否合法
     */
    public function checkRequestAuth()
    {

        //驗證header頭的資訊
        $header = request()->header();
        //halt($header);


        //sign 客戶端工程師加密,服務端工程師解密

        //基礎資料校驗
        //如果sign不存在,報錯
        if (empty($header['sign'])) {
            throw new ApiException('簽名不存在!');
        }

        if (empty($header['apptype'])) {
            throw new ApiException('客戶端不存在!');
        }

        //驗證請求的app客戶端是否合法
        if (!in_array($header['apptype'], config('app.apptypes'))) {
            throw new ApiException('客戶端不合法!', 400);
        }

        //校驗sign
        $header_result = ApiAuth::checkSign($header);

        dump($header_result);

        die();

        if (!$header_result) {
            throw new ApiException('簽名不合法!', 401);
        }
    }
}

同一個簽名,我們修改有效期,若是600s,表示10分鐘內有效,
使用postman請求 ,返回true,表示驗證成功

在這裡插入圖片描述有效期改成10,表示10秒,再使用postman請求 ,返回false,表示驗證失敗
在這裡插入圖片描述

相關文章