Django中send_mail是否支持OAuth2.0(现代认证)及实现方法
Django 邮件发送实现OAuth2.0 方案
核心说明
Django 2.4.57的原生EmailBackend不支持OAuth2.0认证,默认仅提供用户名密码式的SMTP验证。要适配企业禁用SMTP中继的场景,需通过自定义SMTP后端实现OAuth2.0认证。
实现步骤(自定义后端方案)
1. 准备OAuth2.0凭证
根据你的邮件服务提供商(如微软365、Gmail等),提前获取以下信息:
- 客户端ID(Client ID)
- 客户端密钥(Client Secret)
- 刷新令牌(Refresh Token)
- 令牌请求URL(Token URL)
2. 安装依赖库
需要requests库用于获取OAuth2访问令牌:
pip install requests
3. 自定义OAuth2 SMTP后端
创建继承自Django原生EmailBackend的自定义后端,重写SMTP连接逻辑以使用OAuth2认证:
import smtplib from django.core.mail.backends.smtp import EmailBackend from requests import post class OAuth2SMTPBackend(EmailBackend): def __init__(self, oauth2_token_url, oauth2_client_id, oauth2_client_secret, oauth2_refresh_token, **kwargs): self.oauth2_token_url = oauth2_token_url self.oauth2_client_id = oauth2_client_id self.oauth2_client_secret = oauth2_client_secret self.oauth2_refresh_token = oauth2_refresh_token super().__init__(**kwargs) def _get_access_token(self): # 从授权服务器获取访问令牌 response = post( self.oauth2_token_url, data={ 'grant_type': 'refresh_token', 'client_id': self.oauth2_client_id, 'client_secret': self.oauth2_client_secret, 'refresh_token': self.oauth2_refresh_token, }, ) response.raise_for_status() return response.json()['access_token'] def open(self): if self.connection: return False try: access_token = self._get_access_token() # 根据SSL/TLS配置初始化SMTP连接 if self.use_ssl: self.connection = smtplib.SMTP_SSL(self.host, self.port, **self.connection_params) else: self.connection = smtplib.SMTP(self.host, self.port, **self.connection_params) if self.use_tls: self.connection.starttls(**self.connection_params) # 执行OAuth2认证 self.connection.login(self.username, access_token, initial_response_ok=True) return True except smtplib.SMTPException as e: self.close() raise e
4. 在代码中使用自定义后端
替换示例中的参数为你的实际凭证,然后发起邮件发送:
from django.core.mail import EmailMessage # 示例:微软365的OAuth2配置 oauth2_config = { 'oauth2_token_url': 'https://login.microsoftonline.com/common/oauth2/v2.0/token', 'oauth2_client_id': '你的客户端ID', 'oauth2_client_secret': '你的客户端密钥', 'oauth2_refresh_token': '你的刷新令牌', 'host': 'smtp.office365.com', 'port': 587, 'username': '你的邮箱地址', 'use_tls': True, 'use_ssl': False, } # 初始化自定义连接 connection = OAuth2SMTPBackend(**oauth2_config) connection.open() # 发送邮件 msg = EmailMessage( subject="测试OAuth2邮件", body="这是通过OAuth2认证发送的邮件", from_email="你的邮箱地址", to=["收件人邮箱"], connection=connection ) msg.send()
注意事项
- 不同邮件服务商的OAuth2配置存在差异,比如Gmail的令牌URL为
https://oauth2.googleapis.com/token,需根据服务商文档调整参数 - 刷新令牌需通过服务商的授权码流程提前获取,确保令牌具有邮件发送的权限
- 自定义后端兼容Django 2.4.57版本,因为仅重写了原生
EmailBackend的open方法,未依赖高版本特性
内容的提问来源于stack exchange,提问作者Thulasi Das
相关产品推荐
相关产品推荐

