hitrov/oci-api-php-request-sign

此包生成适当的HTTP头,以签名Oracle Cloud Infrastructure API请求

1.2.3 2023-12-23 16:12 UTC

This package is auto-updated.

Last update: 2024-09-23 18:07:49 UTC


README

Latest Stable Version Test

如果您喜欢文章风格,这里有一个链接到 Medium

安装

composer require hitrov/oci-api-php-request-sign

导入类自动加载器

require 'vendor/autoload.php';
use Hitrov\OCI\Signer;

准备凭证

Signer 期望有一个可用的环境变量列表

OCI_TENANCY_ID=ocid1.tenancy.oc1..aaaaaaaaba3pv6wkcr4jqae5f15p2b2m2yt2j6rx32uzr4h25vqstifsfdsq
OCI_USER_ID=ocid1.user.oc1..aaaaaaaat5nvwcna5j6aqzjcaty5eqbb6qt2jvpkanghtgdaqedqw3rynjq
OCI_KEY_FINGERPRINT=20:3b:97:13:55:1c:5b:0d:d3:37:d8:50:4e:c5:3a:34
OCI_PRIVATE_KEY_FILENAME=/path/to/privatekey.pem

还有几种方法可以公开/传递它们,请参阅 本节

基本用法

以下是PHP脚本示例,说明如何为对象存储服务API创建 CreatePreauthenticatedRequest

$signer = new Signer();

$curl = curl_init();

$url = 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/{namespaceName}/b/{bucketName}/p/';
$method = 'POST';
$body = '{"accessType": "ObjectRead", "name": "read-access-to-image.png", "objectName": "path/to/image.png", "timeExpires": "2021-03-01T00:00:00-00:00"}';

$headers = $signer->getHeaders($url, $method, $body, 'application/json');
var_dump($headers);

$curlOptions = [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 5,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => $method,
    CURLOPT_HTTPHEADER => $headers,
];

if ($body) {
    // not needed for GET or HEAD requests
    $curlOptions[CURLOPT_POSTFIELDS] = $body;
}

curl_setopt_array($curl, $curlOptions);

$response = curl_exec($curl);
echo $response;
curl_close($curl);
array(6) {
  [0]=>
  string(35) "date: Mon, 08 Feb 2021 20:49:22 GMT"
  [1]=>
  string(50) "host: objectstorage.eu-frankfurt-1.oraclecloud.com"
  [2]=>
  string(18) "content-length: 76"
  [3]=>
  string(30) "content-type: application/json"
  [4]=>
  string(62) "x-content-sha256: X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE="
  [5]=>
  string(538) "Authorization: Signature version=\"1\",keyId=\"ocid1.tenancy.oc1..aaaaaaaaba3pv6wkcr4jqae5f15p2b2m2yt2j6rx32uzr4h25vqstifsfdsq/ocid1.user.oc1..aaaaaaaat5nvwcna5j6aqzjcaty5eqbb6qt2jvpkanghtgdaqedqw3rynjq/20:3b:97:13:55:1c:5b:0d:d3:37:d8:50:4e:c5:3a:34\",algorithm=\"rsa-sha256\",headers=\"date (request-target) host content-length content-type x-content-sha256\",signature=\"LXWXDA8VmXXc1NRbMmXtW61IS97DfIOMAnlj+Gm+oBPNc2svXYdhcXNJ+oFPoi9qJHLnoUiHqotTzuVPXSG5iyXzFntvkAn3lFIAja52iwwwcJflEIXj/b39eG2dCsOTmmUJguut0FsLhCRSX0eylTSLgxTFGoQi7K/m18nafso=\""
}
{
  "accessUri": "/p/AlIlOEsMok7oE7YkN30KJUDjDKQjk493BKbuM-ANUNGdBBAHzHT_5lFlzYC9CQiA/n/{namespaceName}/b/{bucketName}/o/path/to/image.png",
  "id": "oHJQWGxpD+2PhDqtoewvLCf8/lYNlaIpbZHYx+mBryAad/q0LnFy37Me/quKhxEi:path/to/image.png",
  "name": "read-access-to-image.png",
  "accessType": "ObjectRead",
  "objectName": "path/to/image.png",
  "timeCreated": "2021-02-09T11:52:45.053Z",
  "timeExpires": "2021-03-01T00:00:00Z"
}

就这么多!

提供凭证的替代方案

构造函数参数

$signer = new Signer(
    $ociTenancyId,
    $ociUserId,
    $ociKeyFingerPrint,
    $privateKeyFilename
);

单独的凭证类

实现 Hitrov\OCI\KeyProvider\KeyProviderInterface 方法

  • public function getPrivateKey(): string; // 必须返回一个字符串(privatekey.pem的内容)
  • public function getKeyId(): string; // 必须返回一个字符串,例如 "{OCI_TENANCY_ID}/{OCI_USER_ID}/{OCI_KEY_FINGERPRINT}"

强制 Signer 使用它而不是构造函数参数和环境变量

$keyProvider = new MockKeyProvider() // implements KeyProviderInterface;
$signer = new Signer();
$signer->setKeyProvider($keyProvider);

在单元测试 tests\Hitrov\Test\MockKeyProvider.php 中有一个这样的示例

手动生成步骤

如果您需要它或只是好奇它是如何工作的,还可以公开更多公共方法来处理幕后生成的一切

$signingHeadersNames = $signer->getSigningHeadersNames('POST');
var_dump($signingHeadersNames);
array(6) {
  [0]=>
  string(4) "date"
  [1]=>
  string(16) "(request-target)"
  [2]=>
  string(4) "host"
  [3]=>
  string(14) "content-length"
  [4]=>
  string(12) "content-type"
  [5]=>
  string(16) "x-content-sha256"
}
// the value of `x-content-sha256` HTTP header
$bodyHashBase64 = $signer->getBodyHashBase64($body);
// X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
$signingString = $signer->getSigningString($url, $method, $body, 'application/json');
date: Mon, 08 Feb 2021 20:51:33 GMT
(request-target): post /n/{namespaceName}/b/{bucketName}/p/
host: objectstorage.eu-frankfurt-1.oraclecloud.com
content-length: 76
content-type: application/json
x-content-sha256: X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
// part of `authorization` HTTP header value
$signature = $signer->calculateSignature($signingString, $privateKeyString);
// LXWXDA8VmXXc1NRbMmXtW61IS97DfIOMAnlj+Gm+oBPNc2svXYdhcXNJ+oFPoi9qJHLnoUiHqotTzuVPXSG5iyXzFntvkAn3lFIAja52iwwwcJflEIXj/b39eG2dCsOTmmUJguut0FsLhCRSX0eylTSLgxTFGoQi7K/m18nafso=
// part of `authorization` HTTP header value
$keyId = $signer->getKeyId(); // "{OCI_TENANCY_ID}/{OCI_USER_ID}/{OCI_KEY_FINGERPRINT}"
// ocid1.tenancy.oc1..aaaaaaaaba3pv6wkcr4jqae5f15p2b2m2yt2j6rx32uzr4h25vqstifsfdsq/ocid1.user.oc1..aaaaaaaat5nvwcna5j6aqzjcaty5eqbb6qt2jvpkanghtgdaqedqw3rynjq/20:3b:97:13:55:1c:5b:0d:d3:37:d8:50:4e:c5:3a:34

使用这种方式生成授权头(对于此签名过程,版本总是 1

Authorization: Signature version="1",keyId="{KEY_ID}",algorithm="rsa-sha256",headers="{SIGNING_HEADERS_NAMES_STRING}",signature="{SIGNATURE}"

$signingHeadersNamesString = implode(' ', $signingHeadersNames);
$authorizationHeader = $signer->getAuthorizationHeader($keyId, $signingHeadersNamesString, $signature);
// Authorization: Signature version=\"1\",keyId=\"ocid1.tenancy.oc1..aaaaaaaaba3pv6wkcr4jqae5f15p2b2m2yt2j6rx32uzr4h25vqstifsfdsq/ocid1.user.oc1..aaaaaaaat5nvwcna5j6aqzjcaty5eqbb6qt2jvpkanghtgdaqedqw3rynjq/20:3b:97:13:55:1c:5b:0d:d3:37:d8:50:4e:c5:3a:34\",algorithm=\"rsa-sha256\",headers=\"date (request-target) host content-length content-type x-content-sha256\",signature=\"LXWXDA8VmXXc1NRbMmXtW61IS97DfIOMAnlj+Gm+oBPNc2svXYdhcXNJ+oFPoi9qJHLnoUiHqotTzuVPXSG5iyXzFntvkAn3lFIAja52iwwwcJflEIXj/b39eG2dCsOTmmUJguut0FsLhCRSX0eylTSLgxTFGoQi7K/m18nafso=\"

灵感