如何使用包含 `/` 斜杠字符的密码的电子邮件 URL
How to use an email URL with a password which contains slash character of `/`
对于 Django 应用程序,我尝试将环境变量 EMAIL_URL
设置为 smtp://username:password@email-smtp.us-east-1.amazonaws.com:587/?tls=True
,其中 password
包含 /
.
的斜线字符
出于某种原因,Amazon SES 给了我一个包含 /
个字符的密码。
例如:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
然后运行:
python3.9 manage.py runserver
但是我收到一个错误:
ValueError: Port could not be cast to integer value as 'BFB6UvkMgn9dniEGQZc'
此文件抛出错误:
myapp-venv/lib/python3.9/site-packages/dj_email_url.py
在'EMAIL_PORT': url.port,
这个函数的语句:
def parse(url):
"""Parses an email URL."""
conf = {}
url = urllib.parse.urlparse(url)
qs = urllib.parse.parse_qs(url.query)
# Remove query strings
path = url.path[1:]
path = path.split('?', 2)[0]
# Update with environment configuration
conf.update({
'EMAIL_FILE_PATH': path,
'EMAIL_HOST_USER': unquote(url.username),
'EMAIL_HOST_PASSWORD': unquote(url.password),
'EMAIL_HOST': url.hostname,
'EMAIL_PORT': url.port,
'EMAIL_USE_SSL': False,
'EMAIL_USE_TLS': False,
})
if url.scheme in SCHEMES:
conf['EMAIL_BACKEND'] = SCHEMES[url.scheme]
# ...
return conf
尝试过
我试图用 \
转义 /
但没有成功!
尝试过
根据@bdbd 的建议,尝试使用此语句:
EMAIL_URL = urllib.parse.quote(EMAIL_URL)
就在打电话之前 dj_email_url.parse
:
email_config = dj_email_url.parse(EMAIL_URL)
但问题是,在那种情况下,结果 email_config
将没有 EMAIL_BACKEND
的键。我的意思是,这个语句不能被评估:
EMAIL_BACKEND = email_config["EMAIL_BACKEND"]
代码
调用dj_email_url.parse
的代码是这样的:
EMAIL_URL = os.environ.get("EMAIL_URL")
### Amazon SES password contains slash character,
### trying to fix resulted errors.
### Unfortunately, didn't work.
#EMAIL_URL = urllib.parse.quote(EMAIL_URL)
email_config = dj_email_url.parse(EMAIL_URL)
EMAIL_FILE_PATH = email_config["EMAIL_FILE_PATH"]
EMAIL_HOST_USER = email_config["EMAIL_HOST_USER"]
EMAIL_HOST_PASSWORD = email_config["EMAIL_HOST_PASSWORD"]
EMAIL_HOST = email_config["EMAIL_HOST"]
EMAIL_PORT = email_config["EMAIL_PORT"]
EMAIL_BACKEND = email_config["EMAIL_BACKEND"]
EMAIL_USE_TLS = email_config["EMAIL_USE_TLS"]
EMAIL_USE_SSL = email_config["EMAIL_USE_SSL"]
工作了吗?
根据@JPG的回答,我在设置环境变量时将密码中的/
字符替换为%2F
:
### Replace this:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
### With this:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
看起来它在不需要修改代码的情况下解决了错误!需要更多测试。
首先,标准化您的密码部分(或包含斜杠的部分)
In [2]: from urllib.parse import quote
In [3]: pwd = "BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2"
In [4]: quote(pwd, safe="")
Out[4]: 'BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2'
现在,我们得到了规范化密码字符串。然后,用这个新密码替换 URL 的密码部分。所以,它会变成,
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
例子
In [16]: from urllib.parse import unquote
In [17]: env("EMAIL_URL")
Out[17]: 'smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True'
In [18]: env.email_url('EMAIL_URL')
Out[18]:
{'EMAIL_FILE_PATH': '',
'EMAIL_HOST_USER': 'AKIAYZT73XCKGD',
'EMAIL_HOST_PASSWORD': 'BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2',
'EMAIL_HOST': 'email-smtp.us-east-2.amazonaws.com',
'EMAIL_PORT': 587,
'EMAIL_BACKEND': 'django.core.mail.backends.smtp.EmailBackend',
'OPTIONS': {'TLS': 'True'}}
In [19]: unquote(env("EMAIL_URL"))
Out[19]: 'smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True'
对于 Django 应用程序,我尝试将环境变量 EMAIL_URL
设置为 smtp://username:password@email-smtp.us-east-1.amazonaws.com:587/?tls=True
,其中 password
包含 /
.
出于某种原因,Amazon SES 给了我一个包含 /
个字符的密码。
例如:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
然后运行:
python3.9 manage.py runserver
但是我收到一个错误:
ValueError: Port could not be cast to integer value as 'BFB6UvkMgn9dniEGQZc'
此文件抛出错误:
myapp-venv/lib/python3.9/site-packages/dj_email_url.py
在'EMAIL_PORT': url.port,
这个函数的语句:
def parse(url):
"""Parses an email URL."""
conf = {}
url = urllib.parse.urlparse(url)
qs = urllib.parse.parse_qs(url.query)
# Remove query strings
path = url.path[1:]
path = path.split('?', 2)[0]
# Update with environment configuration
conf.update({
'EMAIL_FILE_PATH': path,
'EMAIL_HOST_USER': unquote(url.username),
'EMAIL_HOST_PASSWORD': unquote(url.password),
'EMAIL_HOST': url.hostname,
'EMAIL_PORT': url.port,
'EMAIL_USE_SSL': False,
'EMAIL_USE_TLS': False,
})
if url.scheme in SCHEMES:
conf['EMAIL_BACKEND'] = SCHEMES[url.scheme]
# ...
return conf
尝试过
我试图用 \
转义 /
但没有成功!
尝试过
根据@bdbd 的建议,尝试使用此语句:
EMAIL_URL = urllib.parse.quote(EMAIL_URL)
就在打电话之前 dj_email_url.parse
:
email_config = dj_email_url.parse(EMAIL_URL)
但问题是,在那种情况下,结果 email_config
将没有 EMAIL_BACKEND
的键。我的意思是,这个语句不能被评估:
EMAIL_BACKEND = email_config["EMAIL_BACKEND"]
代码
调用dj_email_url.parse
的代码是这样的:
EMAIL_URL = os.environ.get("EMAIL_URL")
### Amazon SES password contains slash character,
### trying to fix resulted errors.
### Unfortunately, didn't work.
#EMAIL_URL = urllib.parse.quote(EMAIL_URL)
email_config = dj_email_url.parse(EMAIL_URL)
EMAIL_FILE_PATH = email_config["EMAIL_FILE_PATH"]
EMAIL_HOST_USER = email_config["EMAIL_HOST_USER"]
EMAIL_HOST_PASSWORD = email_config["EMAIL_HOST_PASSWORD"]
EMAIL_HOST = email_config["EMAIL_HOST"]
EMAIL_PORT = email_config["EMAIL_PORT"]
EMAIL_BACKEND = email_config["EMAIL_BACKEND"]
EMAIL_USE_TLS = email_config["EMAIL_USE_TLS"]
EMAIL_USE_SSL = email_config["EMAIL_USE_SSL"]
工作了吗?
根据@JPG的回答,我在设置环境变量时将密码中的/
字符替换为%2F
:
### Replace this:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
### With this:
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
看起来它在不需要修改代码的情况下解决了错误!需要更多测试。
首先,标准化您的密码部分(或包含斜杠的部分)
In [2]: from urllib.parse import quote
In [3]: pwd = "BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2"
In [4]: quote(pwd, safe="")
Out[4]: 'BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2'
现在,我们得到了规范化密码字符串。然后,用这个新密码替换 URL 的密码部分。所以,它会变成,
export EMAIL_URL="smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True"
例子
In [16]: from urllib.parse import unquote
In [17]: env("EMAIL_URL")
Out[17]: 'smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc%2FxM%2FKDS9Agc%2FS2@email-smtp.us-east-2.amazonaws.com:587/?tls=True'
In [18]: env.email_url('EMAIL_URL')
Out[18]:
{'EMAIL_FILE_PATH': '',
'EMAIL_HOST_USER': 'AKIAYZT73XCKGD',
'EMAIL_HOST_PASSWORD': 'BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2',
'EMAIL_HOST': 'email-smtp.us-east-2.amazonaws.com',
'EMAIL_PORT': 587,
'EMAIL_BACKEND': 'django.core.mail.backends.smtp.EmailBackend',
'OPTIONS': {'TLS': 'True'}}
In [19]: unquote(env("EMAIL_URL"))
Out[19]: 'smtp://AKIAYZT73XCKGD:BFB6UvkMgn9dniEGQZc/xM/KDS9Agc/S2@email-smtp.us-east-2.amazonaws.com:587/?tls=True'