问题描述
如何通过TOS API实现对存储对象的GetObject
问题分析
对象存储会对每个访问的请求进行身份验证,因此您需要在请求中包含签名信息,如何通过Python脚本实现API的签名机制
解决方案
下面展示如何使用Python实现API签名并执行GetObject操作
完整Get Object示例代码如下:
import sys, os, base64, datetime, hashlib, hmac
import requests # pip install requests
import json
# ************* REQUEST VALUES *************
method = 'GET'
host = 'bucket-name.tos-cn-beijing.volces.com'
region = 'cn-beijing'
endpoint = 'https://bucket-name.tos-cn-beijing.volces.com'
def sign(key, msg):
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
def getSignatureKey(key, dateStamp, regionName, serviceName):
kDate = sign(key.encode('utf-8'), dateStamp)
kRegion = sign(kDate, regionName)
kService = sign(kRegion, serviceName)
kSigning = sign(kService, 'request')
return kSigning
def sigv4(access_key, secret_key, service, request_parameters):
if access_key is None or secret_key is None:
print('No access key is available.')
sys.exit()
t = datetime.datetime.utcnow()
current_date = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
canonical_uri = '/test.txt'
canonical_querystring = request_parameters
signed_headers = 'host;range;x-tos-content-sha256;x-tos-date'
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()
content_type = 'bytes=0-10'
# 注意:将需要参与签名的header的key全部转成小写, 然后以ASCII排序后以key-value的方式组合后换行构建。
canonical_headers ='host:' + host + '\n' + 'range:' + content_type + '\n' +'x-tos-content-sha256:' + payload_hash + '\n' + 'x-tos-date:' + current_date + '\n'
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
print("1.创建规范请求示例"+'\n',canonical_request)
algorithm = 'TOS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'request'
string_to_sign = algorithm + '\n' + current_date + '\n' + credential_scope + '\n' + hashlib.sha256(
canonical_request.encode('utf-8')).hexdigest()
print("2.创建待签字符串示例"+'\n',string_to_sign)
signing_key = getSignatureKey(secret_key, datestamp, region, service)
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
print("3.Signature示例"+'\n',signature)
authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
print("4.Authorization示例"+'\n',authorization_header)
headers = {'x-tos-date': current_date,
'Authorization': authorization_header,
'x-tos-Content-sha256': payload_hash,
'range': content_type,
}
#打印返回状态码和内容
print('Response code: %d\n' % r.status_code)
print(json.dumps(parsed, indent=4, sort_keys=True))
if __name__ == "__main__":
access_key = 'AKLTYThhOWZkNDU*********mMyZGE1MGMxMTliM2Q'
secret_key = 'WW1Oak1tUTRNekV*********Raamd6WVRObU9UZzRZVGN4WVdRNU1ETQ=='
service = 'tos'
formatted_parameters=''
sigv4(access_key, secret_key, service, formatted_parameters)
Python脚本API签名过程如下:
1.创建一个正规化的请求, 将下面的bucket-name换成自己的S3桶名字,最终CanonicalRequest示例
GET
/test.txt
host:bucket-name.tos-cn-beijing.volces.com
range:bytes=0-10
x-tos-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-tos-date:20220211T091839Z
host;range;x-tos-content-sha256;x-tos-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
2.最终StringToSign
TOS4-HMAC-SHA256
20220211T091839Z
20220211/cn-beijing/tos/request
f7c9062a711358c2b0a525b2b76b478f87065537357089438a58789c168e4b11
3.最终Signature示例
439e82fbeb16feb064a096b7a3916b21a57dc9aae281a0ae6c9c10062049c701
4.最终Authorization示例
TOS4-HMAC-SHA256 Credential=AKLTYThhOWZkNDUwOTdlNDkxOTkzMmMyZGE1MGMxMTliM2Q/20220211/cn-beijing/tos/request, SignedHeaders=host;range;x-tos-content-sha256;x-tos-date, Signature=439e82fbeb16feb064a096b7a3916b21a57dc9aae281a0ae6c9c10062049c701
参考连接
https://www.volcengine.com/docs/6349/74839 https://www.volcengine.com/docs/6349/74856 如果您有其他问题,欢迎您联系火山引擎技术支持服务