この例では、Object Storage Service (OSS) SDK (ソフトウェア開発キット) を使用せずに、Node.js で PutObject リクエストに手動で署名する方法 (署名対象文字列の構築、HMAC-SHA1 署名の計算、Authorization ヘッダーの設定) を示します。
本番アプリケーションでは、OSS SDK を使用してください。SDK を使用できない場合や、基盤となる認証メカニズムを理解する必要がある場合には、手動署名が役立ちます。
前提条件
開始する前に、以下が準備できていることを確認してください:
Node.js v12.10.0 以降がインストールされていること
OSS バケット
バケットへの書き込みアクセス権を持つ AccessKey ID と AccessKey Secret
以下の npm パッケージがインストールされていること:
npm install crypto-js request
署名の仕組み
OSS は、Authorization ヘッダー内の署名を使用して各リクエストを認証します。署名は、リクエストメソッド、コンテンツタイプ、日付、リソースパスをエンコードした署名対象文字列から計算されます。
署名対象文字列の数式:
StringToSign = HTTP-Verb + "\n"
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedResourceAuthorization ヘッダーのフォーマット:
Authorization: OSS <AccessKeyId>:<Signature>
Signature = Base64(HMAC-SHA1(AccessKeySecret, StringToSign))フィールドリファレンス:
| フィールド | 必須 | 説明 |
|---|---|---|
HTTP-Verb | はい | 大文字の HTTP メソッド。例:PUT |
Content-MD5 | いいえ | リクエストボディの MD5 ハッシュ。省略した場合は空の文字列を使用します。 |
Content-Type | いいえ | リクエストボディの MIME タイプ。省略した場合は空の文字列を使用します。 |
Date | はい | GMT フォーマットのリクエスト時刻。例:Mon, 02 Mar 2026 08:00:00 GMT |
CanonicalizedResource | はい | スラッシュで始まるバケット名とオブジェクトキー。例:/mybucket/mytest/nodejs.txt |
例:PutObject リクエストと署名対象文字列のマッピング
Request StringToSign
PUT /mytest/nodejs.txt HTTP/1.1 PUT\n
Content-Type: application/json \n
Date: Mon, 02 Mar 2026 08:00:00 GMT application/json\n
Host: mybucket.oss-cn-hangzhou... Mon, 02 Mar 2026 08:00:00 GMT\n
/mybucket/mytest/nodejs.txtリクエストに Content-MD5 がないため、署名対象文字列では空の文字列になっていることに注意してください。
オブジェクトへの署名とアップロード
次の Node.js コードは、HMAC-SHA1 を使用して PutObject リクエストに署名し、オブジェクトを OSS にアップロードします。
var HmacSha1 = require('crypto-js/hmac-sha1');
var Base64 = require('crypto-js/enc-base64');
var request = require('request');
// 設定 — プレースホルダーを実際の値に置き換えてください
var endpoint = 'http://oss-cn-hangzhou.aliyuncs.com'; // <リージョンエンドポイント>
var bucketName = 'xxx'; // <ご利用のバケット名>
var objectName = 'mytest/nodejs.txt'; // <ご利用のオブジェクト名>
var accesskey = 'xxxx'; // <ご利用の AccessKey ID>
var accesskeysecret = 'xxx'; // <ご利用の AccessKey Secret>
// 署名対象文字列の構築
var gmtDate = (new Date()).toGMTString();
var contenttype = 'application/json';
var strtosign = 'PUT\n\n' + contenttype + '\n' + gmtDate + '\n' + '/' + bucketName + '/' + objectName;
// 署名の計算
var sign = Base64.stringify(HmacSha1(strtosign, accesskeysecret));
// PUT リクエストの送信
var options = {
url: 'http://' + bucketName + '.oss-cn-hangzhou.aliyuncs.com/' + objectName,
headers: {
'Content-Type': contenttype,
'Date': gmtDate,
'Authorization': 'OSS ' + accesskey + ':' + sign
},
body: '{test:test}'
};
request.put(options, function(error, response, body) {
console.info('response: ' + JSON.stringify(response));
console.info('statusCode: ' + response.statusCode);
console.info('body: ' + body);
});次のプレースホルダーを実際の値に置き換えてください:
| プレースホルダー | 説明 | 例 |
|---|---|---|
<region-endpoint> | ご利用のリージョンの OSS エンドポイント | http://oss-cn-hangzhou.aliyuncs.com |
<your-bucket-name> | ご利用のバケット名 | my-bucket |
<your-object-name> | バケット内のターゲットオブジェクトパス | mytest/nodejs.txt |
<your-accesskey-id> | ご利用の AccessKey ID | LTAI5tXxx |
<your-accesskey-secret> | ご利用の AccessKey Secret | xXxXxXx |
トラブルシューティング
`SignatureDoesNotMatch`
このエラーは、OSS がリクエストから計算した署名が、送信された署名と一致しないことを意味します。以下を確認してください:
Dateヘッダーが有効な GMT フォーマットであり、署名対象文字列で使用された値と一致している。署名対象文字列の
Content-Typeが、大文字と小文字を含め、Content-Typeヘッダーと完全に一致している。CanonicalizedResourceが/の後にバケット名とオブジェクトキーが続く形式 (/bucketName/objectName) になっている。リクエストに
Content-MD5またはContent-Typeがない場合、署名対象文字列の該当箇所で空の文字列 ("") を使用している。署名の計算に使用した AccessKey Secret が正しく、ローテーションされていない。
`403 Access Denied`
AccessKey ID と AccessKey Secret が有効であり、関連付けられたアカウントがターゲットバケットに対する oss:PutObject 権限を持っていることを確認してください。
次のステップ
Authorization ヘッダーに署名を含める — OSS リクエスト署名の完全な仕様