CloudapiSign.php 2.0 KB
<?php


namespace app\common\library\cloudapi;

use think\Exception;

/**
 * 云API签名工具类
 * Class CloudapiSign
 * @package app\common\library
 */
class CloudapiSign
{
    public static function sign($data){
        if (empty($data) || !is_array($data)){
            throw new Exception(ErrorCode::getMessage(ErrorCode::FAILED_SIGN), ErrorCode::FAILED_SIGN);
        }

        if (!isset($data['app_secret'])){
            throw new Exception(ErrorCode::getMessage(ErrorCode::NOT_HAVE_APP_SECRET), ErrorCode::NOT_HAVE_APP_SECRET);
        }

        //去除参数中的sign
        if (isset($data['sign'])){
            unset($data['sign']);
        }

        //对数组进行键名排序
        ksort($data);

        //把数组中非空参数拼接成url参数形式的字符串:如age=10&name=小明
        $dataStr = '';
        foreach ($data as $key => $v){
            if (!empty($v)){
                $dataStr .= $key . '=' . $v . '&';
            }
        }
        $dataStr = trim($dataStr, '&');

        //对字符串进行加密
        $sign = hash_hmac('sha256', $dataStr, $data['app_secret'],true);
        $signature = base64_encode($sign);

        return $signature;
    }

    public static function check($data){
        if (!isset($data['sign'])){
            throw new Exception(ErrorCode::getMessage(ErrorCode::NOT_HAVE_SIGN), ErrorCode::NOT_HAVE_SIGN);
        }
        if (!isset($data['timestamp'])){
            throw new Exception(ErrorCode::getMessage(ErrorCode::NOT_HAVE_TIMESTAMP), ErrorCode::NOT_HAVE_TIMESTAMP);
        }

        $sign = $data['sign'];
        try {
            $signNew = self::sign($data);
        } catch (Exception $e) {
            throw $e;
        }
        if ($sign !== $signNew){
            throw new Exception(ErrorCode::getMessage(ErrorCode::VERIFICATION_FAILED), ErrorCode::VERIFICATION_FAILED);
        }
        if (time() - $data['timestamp'] > 5){
            throw new Exception(ErrorCode::getMessage(ErrorCode::INVALID_SIGN), ErrorCode::INVALID_SIGN);
        }
        return true;
    }

}