thinkphp中api接口数据安全解决方案之sign检验

26 篇文章 0 订阅
文章介绍了在ThinkPHP框架中实现API接口数据安全的一种方案,通过Sign签名检验确保数据完整性和安全性。ApiAuth类用于签名的生成和校验,使用Aes加密解密类进行数据加密,同时定义了ApiException异常处理类来处理校验失败的情况。配置文件中定义了相关参数,如aeskey和apptypes,以配合客户端进行签名验证。
摘要由CSDN通过智能技术生成

thinkphp中api接口数据安全解决方案之sign检验

目录

thinkphp中api接口数据安全解决方案之sign检验

封装校验类ApiAuth.php

           Common类中调用校验方法

           抛出异常类ApiException

           app.php配置文件

           Aes加密解密类


封装校验类ApiAuth.php

namespace app\common\lib;
use app\common\lib\ApiAuth;
    class ApiAuth
    {
        /**
        * 1,sign算法加密
        */
        public static function setSign($data = [])
        {
            //(1)按字段排序
            ksort($data);
            //(2)拼接数据
            $sign_str = http_build_query($data);//作用是生成通过 URL 编码后的查询字符串。(即上面的 content=111&list=12&user=12 这个部分)
            //(3)通过aes加密
            return (new Aes())->encrypt($sign_str);
            //$string = $this->encrypt($string);
            //return $string;
        }

        /**
        * 检查sign是否正常
        * @param array $data
        */
        public static function checkSign($data)
        {
            //解密
            $str = (new Aes())->decrypt($data['sign']);
            if (!$str) {
                return false;
            }
            //将字符串你转成数组格式
            parse_str($str, $arr);
            //比较
            if (!is_array($arr) || $arr['name'] != 'qipa250') {
                return false;
            }
            return true;
        }
    }
 }

Common类中调用校验方法

在api模块的控制器中,建立公共的common类,别的类继承此类 

class Common extends Controller{//新建的公共文件  Common

     public $headers = '';
     /*
     * 初始化方法
     */
    public function _initialize()
    {
          $this->checkRequestAuth();
    }
    /*
    * 检查每次app请求的数据是否合法
    */
    public function checkRequestAuth()
    {

        //首先获取headers
        //use think\Request;
        $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();
    }
}

抛出异常类ApiException

<?php

namespace app\common\lib\exception;
//引用异常类
use think\Exception;
//继承异常类
class ApiException extends Exception
{
    //自定义http状态码
    public $message = '';
    public $httpCode = 400;
    public $code = 0;

    /*
     * 渲染抛出异常的状态码和信息
     */
    public function __construct($message = "", $httpCode = 0, $code = 0)
    {
        $this->message = $message;
        $this->httpCode = $httpCode?:400;
        $this->code = $code;
    }
}

app.php配置文件

<?php

return [
    'admin_password_pre' => '_qipa250',//后台管理员密码加密后缀
    'aeskey' => 'QiPa250',//aes 密钥,服务端和客户端保持一致
    'aesiv' => '12345678901234567890123456789012',//aes iv,服务端和客户端保持一致
    'apptypes' => ['ios', 'android', 'wechat'],
];

Aes加密解密类


    namespace app\common\lib;
    use app\common\lib\Aes;
    class Aes
    {
        private $key = null;
        private $iv = null;
        public function __construct()
        {
            // 需要小伙伴在配置文件app.php中定义aeskey
            $this->iv = config('app.aesiv');
            $this->key = config('app.aeskey');
            $this->key = hash('sha256', $this->key, true);
        }
        public function encrypt($input)
        {
            $data = openssl_encrypt($input, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->hexToStr($this->iv));
            $data = base64_encode($data);
            return $data;
        }
        public function decrypt($input)
        {
            $decrypted = openssl_decrypt(base64_decode($input), 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->hexToStr($this->iv));
            return $decrypted;
        }
        function hexToStr($hex)
        {
            $string = '';
            for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
                $string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
            }
            return $string;
        }

    }

postman请求,返回true 表示签名验证成功

返回false,表示签名验证失败

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值