我的应用程序有一个现有的模块,用于发送访问SMTP服务器并使用用户(邮箱地址)和密码进行授权的邮箱.现在我正试着用我的Gmail账户来做同样的事情,为了不引起争论,我们说它是boboo@gmail.com(它实际上是不同的).
首先,我创建了一个Gmail应用程序.在同意屏幕上,我开始添加"敏感"或"受限"的作用域,这有点令人困惑.如果我想让应用程序"生产",我被告知它必须经过验证过程,我必须生成某些文档.这不适合我,因为我作为这个帐户的所有者,只是为了通过编程发送邮箱而try 连接到它.我为一个桌面应用程序创建了凭据,并将其下载到文件credentials.json.
接下来,我使用以下代码获取了一个访问令牌:
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ['https://mail.google.com/']
def get_initial_credentials(*, token_path, credentials_path):
flow = InstalledAppFlow.from_client_secrets_file(credentials_path, SCOPES)
creds = flow.run_local_server(port=0)
with open(token_path, 'w') as f:
f.write(creds.to_json())
if __name__ == '__main__':
get_initial_credentials(token_path='token.json', credentials_path='credentials.json')
一个浏览器窗口打开,显示这不是一个经过验证的应用程序,我有机会"返回到安全地带",但我点击了"高级"链接,最终拿到了我的令牌.
然后,我try 发送包含以下代码的邮箱:
import smtplib
from email.mime.text import MIMEText
import base64
import json
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ['https://www.googleapis.com/auth/gmail.send']
def get_credentials(token_path):
with open(token_path) as f:
creds = Credentials.from_authorized_user_info(json.load(f), SCOPES)
if not creds.valid:
creds.refresh(Request())
with open(token_path, 'w') as f:
f.write(creds.to_json())
return creds
def generate_OAuth2_string(access_token):
auth_string = f'user=booboo\1auth=Bearer {access_token}\1\1'
return base64.b64encode(auth_string.encode('utf-8')).decode('ascii')
message = MIMEText('I need lots of help!', "plain")
message["From"] = 'booboo@gmail.com'
message["To"] = 'booboo@gmail.com'
message["Subject"] = 'Help needed with Gmail'
creds = get_credentials('token.json')
xoauth_string = generate_OAuth2_string(creds.token)
with smtplib.SMTP('smtp.gmail.com', 587) as conn:
conn.starttls()
conn.docmd('AUTH', 'XOAUTH2 ' + xoauth_string)
conn.sendmail('booboo', ['booboo@gmail.com'], message.as_string())
这是可行的,但请注意,我使用了不同的作用域100,而不是我用来获取初始访问令牌的101.
然后,我编辑了应用程序以添加作用域100.这要求我将应用程序置于测试模式.我不理解添加"测试用户"的部分,也就是说我不知道我可以/应该在这里输入什么.然后,我如上所述生成了新的凭据和新的令牌.然后,当我发送邮箱时,我看到(调试打开):
...
reply: b'535-5.7.8 Username and Password not accepted. Learn more at\r\n'
reply: b'535 5.7.8 https://support.google.com/mail/?p=BadCredentials l19-20020ac84a93000000b0041b016faf7esm2950068qtq.58 - gsmtp\r\n'
reply: retcode (535); Msg: b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials l19-20020ac84a93000000b0041b016faf7esm2950068qtq.58 - gsmtp'
...
但我从未发送过密码,而是发送了XOAUTH2授权字符串.我不知道这是否因为我没有添加测试用户而发生.无论如何,我不相信这个新的令牌已经过期,因此它没有被刷新.
我没有try 过,但如果我将应用程序设置为"Products",它会工作吗?再说一次,我不想用Gmail经历一个完整的验证过程.不幸的是,除了我想定义一个范围更受限制的应用程序并使用它之外,我没有其他特定的问题,但如果不经过这个验证,这似乎是不可能的.有什么建议吗?