在云计算领域,Amazon Web Services (AWS) 提供了一套强大的服务,包括计算、存储、数据库、分析、机器学习等,为了方便开发者使用这些服务,AWS 提供了各种编程语言的 SDK,其中 Python 的 SDK 叫做 boto3,在使用 boto3 的过程中,可能会遇到一些错误,其中之一就是 "botocore.exceptions.NoCredentialsError: Unable to locate credentials",这个错误通常发生在尝试使用 AWS4 签名算法时,本文将详细介绍如何解决这个问题。
我们需要了解什么是 AWS4,AWS4 是 Amazon Web Services (AWS) 的第四版签名协议,用于 HTTP/HTTPS 请求的身份验证和授权,AWS4 使用 HMAC-SHA256 算法对请求进行签名,并使用 Date 头部和 CanonicalURI、CanonicalQueryString、RequestPayload、SignatureHeaders、SignedHeaders、X-Amz-Content-Sha256、Authorization 头部等信息生成签名。
当使用 boto3 发送请求时,如果遇到 "botocore.exceptions.NoCredentialsError: Unable to locate credentials" 错误,通常是因为没有正确配置 AWS 凭证,AWS 凭证包括 Access Key ID、Secret Access Key、SessionToken(可选)和默认的区域名称,这些凭证需要通过以下方式提供:
1. 环境变量:可以在操作系统的环境变量中设置 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY 和 AWS_SESSION_TOKEN。
2. 配置文件:可以在用户主目录下的 .aws/credentials 文件中设置 Access Key ID、Secret Access Key 和默认的区域名称。
```
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
3. IAM Roles:可以在运行 boto3 代码的实例上配置 IAM Roles,IAM Roles 是一种权限管理服务,可以自动为 AWS 资源分配角色。
4. IAM User:可以在运行 boto3 代码的实例上配置 IAM User,IAM User 是一种身份认证服务,可以为每个用户分配一个唯一的 Access Key ID 和 Secret Access Key。
在了解了如何解决 "botocore.exceptions.NoCredentialsError: Unable to locate credentials" 错误之后,我们还需要了解如何使用 boto3 支持 AWS4,boto3 支持 AWS4 的方式是通过配置签名版本和区域名称,签名版本需要在请求的 URL 中指定,区域名称需要在请求的头部中指定,以下是一个简单的示例:
```python
import boto3
from botocore.config import Config
from datetime import datetime, timedelta
import hmac
import hashlib
import base64
import urllib.parse
# 创建 boto3 客户端
client = boto3.client('s3', region_name='us-west-2', config=Config(signature_version='s3v4'))
# 设置请求参数
bucket = 'your-bucket'
key = 'your-key'
date = datetime.utcnow().strftime('%Y%m%d')
region = 'us-west-2'
service = 's3'
amz_date = date + 'T000000Z'
amz_headers = 'host;x-amz-content-sha256;x-amz-date'
canonical_uri = '/' + bucket + '/' + key
canonical_querystring = ''
algorithm = 'AWS4-HMAC-SHA256'
credentials_scope = date + '/' + region + '/' + service + '/' + 'aws4_request'
signing_key = get_signing_key(credentials_scope, 'aws4_request')
signature = sign(canonical_uri, algorithm, signing_key, credentials_scope)
authorization = 'AWS4-HMAC-SHA256 ' + amz_date + ' ' + region + '/' + service + ' ' + 'aws4_request' + ' ' + signature
headers = {'Host': 'your-bucket.s3.amazonaws.com', 'x-amz-content-sha256': base64.b64encode(hmac.new(get_hashing_key(credentials_scope), msg=key, digestmod=hashlib.sha256).digest()), 'x-amz-date': amz_date}
url = client.generate_presigned_url('get_object', ExpiresIn=3600, Params={'Bucket': bucket, 'Key': key}, Method='GET', Headers=headers)
print(url)
在这个示例中,我们首先创建了一个 boto3 客户端,然后设置了请求参数,包括桶名、键名、日期、区域、服务、日期字符串、头字符串、规范的 URL、规范的查询字符串、算法、凭据范围、签名密钥、签名和授权,我们生成了预签名的 URL,并打印出来。
解决 "botocore.exceptions.NoCredentialsError: Unable to locate credentials" 错误的方法是在运行 boto3 代码的环境中正确配置 AWS 凭证,而使用 boto3 支持 AWS4 的方法是在请求的 URL 中指定签名版本和在请求的头部中指定区域名称,希望本文能帮助你解决在使用 boto3 时遇到的问题。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/4956.html