我正在开发一个允许用户使用 Gmail 进行身份验证并发送电子邮件的应用程序。
这是需要发生的事情:
- 用户使用 OAuth2 进行身份验证
- 获取用户的电子邮件地址(或任何其他持久唯一标识符)并用于将用户登录到应用程序
- 用户可以使用 SMTP 撰写和发送电子邮件
但是,我遇到了身份验证问题。我正在使用的函数是 OAuth2WebServerFlow():
flow = OAuth2WebServerFlow(client_id=GOOGLE_CLIENT_ID,
client_secret=GOOGLE_CLIENT_SECRET,
scope=scope,
redirect_uri=base_app_url + '/oauth2callback')
这在scope='https://mail.google.com/ ' 时效果很好,但问题是我无法获取用户的电子邮件地址,因为用户没有授予该权限(如https://developers所示.google.com/oauthplayground/)。结果,我不得不硬编码自己的电子邮件地址才能使其正常工作。
另一方面,当scope='https://mail.google.com/,https://www.googleapis.com/auth/userinfo.email'时,我可以使用以下内容获取用户的电子邮件地址:
r = requests.get('https://www.googleapis.com/oauth2/v2/userinfo',
headers={'Authorization': 'OAuth ' + access_token})
然而,这种情况下的问题是,当我去发送电子邮件时,用于创建身份验证字符串的 access_token 不被接受,这给了我以下错误(我认为这是一个不合适的错误):
SMTPSenderRefused: (535,
'5.7.1 Username and Password not accepted. Learn more at\n5.7.1 http://support.google.com/mail/bin/answer.py?answer=14257 cv19sm54718503vdb.5',
u'<MY_NAME@MY_GOOGLE_APP_DOMAIN.COM>')
这是我发送电子邮件的代码:
def send_email(user_address, access_token, recipient_address, subject, body):
xoauth2_string = 'user=%s\1auth=Bearer %s\1\1' % (user_address, access_token)
url = "https://mail.google.com/mail/b/" + user_address + "/smtp/"
conn = smtplib.SMTP('smtp.gmail.com', 587)
conn.set_debuglevel(True)
conn.ehlo()
conn.starttls()
conn.ehlo()
conn.docmd('AUTH', 'XOAUTH2 ' + base64.b64encode(xoauth2_string))
header = 'To:' + recipient_address + '\n'
header += 'From:' + user_address + '\n'
header += 'Subject:' + subject + ' \n'
header += 'Content-Type: text/html; charset=UTF-8\n'
msg = header + '\n ' + body + ' \n\n'
conn.sendmail(user_address, recipient_address, msg)
基本上我想知道是否:
- 我可以使用 scope='https://mail.google.com/' 获取用户的电子邮件或其他一些持久的唯一标识符。
- 有一种方法可以使 SMTP 与 scope='https://mail.google.com/,https://www.googleapis.com/auth/userinfo.email' 一起工作。
为什么我的身份验证字符串被拒绝?有什么我想念的吗?请求多个权限时google api有问题吗?