我正在使用 PHP 系统访问 blob 系统并使用 SAS 令牌上传一些图像。我可以在没有 SAS 令牌、公共令牌但私有令牌的情况下正确上传图像,但我收到此错误:
InvalidAuthenticationInfo未以正确的格式给出身份验证信息。检查授权标头的值。请求 ID: [xxx]**
我与您分享我的 PHP 代码来执行此操作。首先,我有一个 PHP 文件,其中包含两个用于上传的函数:
function getAccessKey(){
return strval("xxx");
}
function getSASForBlob($accountName,$container, $blob, $resourceType, $permissions, $expiry) {
$key = getAccessKey();
/* Create the signature */
$_arraysign = array();
$_arraysign[] = $permissions;
$_arraysign[] = '';
$_arraysign[] = $expiry;
$_arraysign[] = '/' . $accountName . '/' . $container . '/' . $blob;
$_arraysign[] = '';
$_arraysign[] = "2014-02-14"; //the API version is now required
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_str2sign = implode("\n", $_arraysign);
return base64_encode(
hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($key), true)
);
}
function uploadBlob($filepath, $storageAccountname, $containerName, $blobName, $_signature) {
$accesskey = getAccessKey();
$extUsed = explode(".",$filepath)[3];
//$filepath = $filepath.'.'.$extUsed;
$Date = gmdate('D, d M Y H:i:s \G\M\T');
$handle = fopen($filepath, "r");
$fileLen = filesize($filepath);
$blobName = $blobName.".".$extUsed;
$URL = "https://$storageAccountname.blob.core.windows.net/$containerName/$blobName";
$expiry = '';
$resourceType = 'b';
$permissions = 'r';
$_parts = array();
$_parts[] = (!empty($expiry))?'se=' . urlencode($expiry):'';
$_parts[] = 'sr=' . $resourceType;
$_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
$_parts[] = 'sig=' . urlencode($_signature);
$_parts[] = 'sv=2014-02-14';
$URL = $URL . "?" . implode('&', $_parts);
$headerResource = "x-ms-blob-cache-control:max-age=3600\nx-ms-blob-type:BlockBlob\nx-ms-date:$Date\nx-ms-version:2017-11-09";
$urlResource = "/$storageAccountname/$containerName/$blobName";
$extUsed_folded = 'image/'.$extUsed;
$arraysign = array();
$arraysign[] = 'PUT'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = $fileLen; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = $extUsed_folded /*'application/pdf'*/; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
$arraysign[] = ''; /*If-Unmodified-Since*/
$arraysign[] = ''; /*Range*/
$arraysign[] = $headerResource; /*CanonicalizedHeaders*/
$arraysign[] = $urlResource; /*CanonicalizedResource*/
$str2sign = implode("\n", $arraysign);
$sig = base64_encode(hash_hmac('sha256', urldecode(utf8_encode($str2sign)), base64_decode($accesskey), true));
// $sig = signWithAccountKey($str2sign, getAccessKey());
$authHeader = "SharedKey $storageAccountname:$sig";
$header_contentType = "image/".$extUsed;
switch($extUsed){
case "jpg": case "jpeg": default: break;
case "png":
$header_contentType = "image/png"; break;
case "tiff":
$header_contentType = "image/tiff"; break;
}
$headers = [
'Authorization: ' . $authHeader,
'x-ms-blob-cache-control: max-age=3600',
'x-ms-blob-type: BlockBlob',
'x-ms-date: ' . $Date,
'x-ms-version: 2017-11-09',
'Content-Type: '.$header_contentType,
'Content-Length: ' . $fileLen
];
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $URL );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_INFILE, $handle);
curl_setopt($ch, CURLOPT_INFILESIZE, $fileLen);
curl_setopt($ch, CURLOPT_UPLOAD, true);
$result = curl_exec($ch);
// echo ('Uploaded successfully<br/>');
// print_r($result);
curl_close($ch);
$resultsList = array( $URL , $filepath , $result , $blobName, $urlResource , $accesskey );
if (isset($resultsList) && is_array($resultsList)) {
return $resultsList;
} else {
return array();
}
}
在通过包含到我的主要 PHP 代码中调用此函数后,我执行以下操作:
$blobName = 'image-viajes';
$urlAdjunto = '';
$newFilename = '../Imagenes/temp_viajes.jpg';
if (!empty($filename)){
$blobSignature = getSASForBlob('xxx', 'yyy', $blobName,
'b', 'r', '');
echo '<br /><b>BLOB SIGNATURE</b><p>'.$blobSignature.'</p>';
//$blobFotoAdjunta__url = '';
$blobFotoAdjunta = uploadBlob(
$newFilename,
'xxx', 'yyy',
$blobName, $blobSignature);
}
我尝试将除 url 之外的部分退出到 UploadBlob 函数中,并且它已正确上传到服务器,但没有令牌。当我将 GET 变量添加到 URL 中时,出现此错误。我在 Azure 面板中为我选择的容器生成了这个。
我用 XXX、yyy 等修改了一些数据,但我可以说 public 的变量是正确的。问题出在令牌上。如果您能发现其中的问题,我将非常感谢您。
有任何问题,我都有。我不知道我是否正确地解释了自己。
使用私有 SAS 令牌将图像上传到 Azure 服务器,但无法正常工作。公开上传正确。
尝试使用 SAS 令牌将 blob 图像上传到 Azure 系统
我同意 Gaurav Mantri 的评论。您需要使用其中之一,并且可以使用
Azure Storage SDK for PHP
创建 SAS 令牌。
在我的环境中,我首先使用以下命令克隆存储库:
git clone https://github.com/Azure/azure-storage-blob-php.git
接下来,我使用
composer install
安装了所有依赖项,并在根目录中创建了一个名为 sample.php
的 PHP 文件。
代码:
<?php
require_once 'vendor/autoload.php'; // Autoload dependencies
require_once 'src/Blob/BlobSharedAccessSignatureHelper.php';
use MicrosoftAzure\Storage\Blob\BlobSharedAccessSignatureHelper;
// Replace these values with your Azure Storage account details
$accountName = 'venkat789';
$accountKey = '<Your-account-key>';
$containerName = 'sample';
$blobName = 'sample.png';
// Create BlobSharedAccessSignatureHelper instance
$blobSasHelper = new BlobSharedAccessSignatureHelper($accountName, $accountKey);
// Generate a shared access signature for the blob
$signedResource = 'b'; // Blob resource type
$resourceName = $containerName . '/' . $blobName;
$signedPermissions = 'rw'; // Read permission
$signedExpiry = new DateTime('2024-04-01T00:00:00Z');
$sasToken = $blobSasHelper->generateBlobServiceSharedAccessSignatureToken(
$signedResource,
$resourceName,
$signedPermissions,
$signedExpiry,
);
// Construct the full URI with the generated SAS token
$blobUriWithSas = "https://$accountName.blob.core.windows.net/$containerName/$blobName?$sasToken";
// Replace with the path to the file you want to upload
$filePath = 'C:\zzzzz\mountainview.png';
// Use cURL to upload the blob with SAS token
$handle = fopen($filePath, 'r');
$fileLen = filesize($filePath);
$headers = [
'Content-Length: ' . $fileLen,
'x-ms-blob-type: BlockBlob',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $blobUriWithSas);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // Enable SSL verification
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_INFILE, $handle);
curl_setopt($ch, CURLOPT_INFILESIZE, $fileLen);
curl_setopt($ch, CURLOPT_UPLOAD, true);
$result = curl_exec($ch);
if ($result === false) {
echo 'Curl error: ' . curl_error($ch) . PHP_EOL;
} else {
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 200 && $httpCode < 300) {
echo 'Upload successful.' . PHP_EOL;
} else {
echo 'Upload failed. HTTP Code: ' . $httpCode . PHP_EOL;
echo 'Response: ' . $result . PHP_EOL;
}
}
curl_close($ch);
fclose($handle);
?>
上述脚本使用共享访问签名 (SAS) 令牌将文件上传到 Azure Blob 存储。它生成具有读写权限的 SAS 令牌,该令牌将于 2024 年 4 月 1 日到期。该脚本使用 SAS 令牌构造 blob 的完整 URI,并使用 cURL 将文件上传到 blob。最后输出一条消息,指示上传是否成功。
输出:
Upload successful.
传送门