使用Django+Boto3+AWS SES时verify_email_identity为何用不同IAM凭证?
排查Django Amazon SES与Boto3凭证不一致的问题
这问题我之前帮人排查过,核心原因是django_amazon_ses.EmailBackend和直接调用boto3.client()的凭证加载逻辑优先级不同——哪怕你没在Django代码里手动设置,它们可能从不同的配置路径获取了不同IAM用户的凭证。下面给你一步步拆解排查方向:
1. 先查Django项目的settings.py
django-amazon-ses会优先读取Django配置文件里的AWS相关参数,你先检查settings.py里有没有这类配置:
# settings.py 里可能存在的配置项 AWS_ACCESS_KEY_ID = "IAM用户A的Access Key" AWS_SECRET_ACCESS_KEY = "IAM用户A的Secret Key" # 或者是SES专属配置 SES_ACCESS_KEY_ID = "IAM用户A的Access Key" SES_SECRET_ACCESS_KEY = "IAM用户A的Secret Key"
如果有这些配置,EmailBackend会直接用这里的凭证——这就是它用IAM用户A的原因。
2. 再看Boto3的默认凭证加载路径
直接调用boto3.client()时,Boto3会按以下优先级找凭证(从高到低):
- 代码里显式传入的密钥参数(你这里没传,跳过)
- 环境变量:检查你的终端/服务器环境里
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY是不是设成了IAM用户B的 - AWS本地凭证文件:默认路径是
~/.aws/credentials,看看这个文件里的默认profile是不是用户B的:# ~/.aws/credentials 示例内容 [default] aws_access_key_id = IAM用户B的Access Key aws_secret_access_key = IAM用户B的Secret Key - IAM角色(如果是在EC2/EKS等AWS服务上运行,但这种情况一般不会出现两个不同用户,除非实例角色是用户B,而Django硬编码了用户A)
3. 理解两者的核心差异
关键在于:django-amazon-ses如果在settings.py里找到了AWS/SES的密钥,会直接忽略环境变量和本地凭证文件;而Boto3会优先看环境变量或本地凭证(除非你代码里显式指定)。所以很大概率是你在Django配置里写了用户A的密钥,而系统环境或本地凭证文件是用户B的,导致两者用了不同的IAM用户。
4. 快速验证方法
可以在代码里加几行打印,直接确认两者用的凭证:
# 查看django-amazon-ses用的密钥 from django_amazon_ses import EmailBackend conn = EmailBackend() print("Django SES用的Access Key:", conn.access_key_id) # 查看Boto3用的密钥 import boto3 session = boto3.Session() credentials = session.get_credentials() print("Boto3用的Access Key:", credentials.access_key)
按照上面的步骤排查,很快就能找到问题所在啦。
内容的提问来源于stack exchange,提问作者Axil
相关产品推荐
相关产品推荐

