解决使用 aws-sdk-php 向天翼云对象存储请求 STS 临时凭证报错的问题

本人近期在使用天翼云部署一个 PHP 开发的系统时,在使用 aws-sdk-php 向天翼云对象存储发起STS临时凭证请求时,遇到了如下报错:

Fatal error: Uncaught Aws\Api\Parser\Exception\ParserException: Invalid timestamp value passed to DateTimeResult::fromTimestamp in /data/htdocs/myapp/vendor/aws/aws-sdk-php/src/Api/DateTimeResult.php:100

经过对 aws-sdk-php 源代码进行分析后,决定自己动手进行一些改造,让 aws-sdk-php 兼容天翼云,具体方法如下:

第一步,在 /vendor/aws/aws-sdk-php/src/Api/DateTimeResult.php 中新增一个方法,代码如下:

public static function rectificationTimestamp($timestamp)
{
    if (strpos($timestamp, ".") > 0 && strpos($timestamp, "Z") > 0) {
        $startIndex = strpos($timestamp, ".") + 1;
        $endIndex = strpos($timestamp, "Z") + 1;
        if ($endIndex - $startIndex - 1 > 6) {
            $timestamp = substr($timestamp, 0, $startIndex + 6) . 'Z';
        }
    }        
    return $timestamp;
}

 

第二步,在 fromTimestamp 方法中调用,例如:

public static function fromTimestamp($timestamp, $expectedFormat = null)
{
    if (empty($timestamp)) {
        return self::fromEpoch(0);
    }
    
    // 这里调用 rectificationTimestamp 方法
    $timestamp = self::rectificationTimestamp($timestamp);
    
    if (!(is_string($timestamp) || is_numeric($timestamp))) {
        throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
    }

    try {
        if ($expectedFormat == 'iso8601') {
            try {
                return self::fromISO8601($timestamp);
            } catch (Exception $exception) {
                return self::fromEpoch($timestamp);
            }
        } else if ($expectedFormat == 'unixTimestamp') {
            try {
                return self::fromEpoch($timestamp);
            } catch (Exception $exception) {
                return self::fromISO8601($timestamp);
            }
        } else if (\Aws\is_valid_epoch($timestamp)) {
            return self::fromEpoch($timestamp);
        }
        
        return self::fromISO8601($timestamp);
    } catch (Exception $exception) {
        throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
    }
}

 

通过上述改造,经过反复测试,已经可以正常向天翼云请求获取到 STS 临时凭证的信息。通过分析,应该是天翼云的对象存储返回的时间格式有些问题,导致 aws-sdk-php 无法正常解析,相关问题已经反馈给天翼云,但尚未解决,只好自己动手修改 aws-sdk-php 的源代码来做个兼容。

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

相关内容:

发表评论