hitrov / oci-api-php-request-sign
此包生成适当的HTTP头,以签名Oracle Cloud Infrastructure API请求
1.2.3
2023-12-23 16:12 UTC
Requires
- php: ^7.4 || ^8.0 || ^8.1 || ^8.2 || ^8.3
- ext-openssl: *
Requires (Dev)
- phpunit/phpunit: ^9
README
如果您喜欢文章风格,这里有一个链接到 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=\"