如何使用Twisted检查带有OAuth2.0身份验证的Gmail

2024-09-30 20:34:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个用于googlemail的IMAP客户端,但是它最近停止工作了。我认为问题在于gmail不再允许TTL用户名/密码登录,而现在需要OAuth2.0。在

我想知道修改下面示例的最佳方法,以便twisted IMAP客户端使用OAuth2.0进行身份验证。(如果可能的话,在没有googleapi包的情况下也可以这样做。)

使用用户名/密码登录的示例(不再有效)

class AriSBDGmailImap4Client(imap4.IMAP4Client):
    '''
    client to fetch and process SBD emails from gmail. the messages
    contained in the emails are sent to the AriSBDStationProtocol for
    this sbd modem.
    '''

    def __init__(self, contextFactory=None):
        imap4.IMAP4Client.__init__(self, contextFactory)

    @defer.inlineCallbacks
    def serverGreeting(self, caps):
        # log in
        try:
            # the line below no longer works for gmail
            yield self.login(mailuser, mailpass)
            try:
                yield self.uponAuthentication()
            except Exception as e:
                uponFail(e, "uponAuthentication")
        except Exception as e:
            uponFail(e, "logging in")

        # done. log out
        try:
            yield self.logout()
        except Exception as e:
            uponFail(e, "logging out")

    @defer.inlineCallbacks
    def uponAuthentication(self):
        try:
            yield self.select('Inbox')
            try:
                # read messages, etc, etc
                pass
            except Exception as e:
                uponFail(e, "searching unread")
        except Exception as e:
            uponFail(e, "selecting inbox")

我有一个小工厂为这个客户。它首先使用reactor.connectSSL和googlemail的主机url和端口。在

我已经按照https://developers.google.com/gmail/api/quickstart/quickstart-python上的说明为一个“已安装的应用程序”(但我不知道这是否是正确的选择)。我可以运行他们的“快速入门.py“成功的例子。在

我快速而肮脏的尝试(无效)

^{pr2}$

我基本上只是抄了一遍”快速入门.py,然后尝试将客户端状态设置为“auth”。在

这可以很好地进行身份验证,但twisted无法选择收件箱:

[AriSBDGmailImap4Client (TLSMemoryBIOProtocol),client] FAIL: Unknown command {random gibberish}

随机胡言乱语有字母和数字,每次selectinbox命令失败时都是不同的。在

谢谢你的帮助!在


Tags: theinself客户端defasexceptiongmail
1条回答
网友
1楼 · 发布于 2024-09-30 20:34:43

经过大量的阅读和测试,我终于能够使用OAuth2实现gmail的工作登录。在

一个重要的注意事项是,使用“服务帐户”的两步流程对我不起作用。我仍然不清楚为什么不能使用这个过程,但是服务帐户似乎不能在同一个帐户中访问gmail。即使服务帐户具有“可以编辑”权限并且启用了gmailapi,也是如此。在

有用的参考资料

使用概述 OAuth2https://developers.google.com/identity/protocols/OAuth2

OAuth2与“已安装的应用程序”一起使用指南 https://developers.google.com/identity/protocols/OAuth2InstalledApp

将OAuth2用于“已安装的应用程序”的帐户设置指南 https://developers.google.com/api-client-library/python/auth/installed-app

没有完整googleapi的OAuth2例程的集合 https://code.google.com/p/google-mail-oauth2-tools/wiki/OAuth2DotPyRunThrough

第1步-获取Google客户端ID

使用gmail帐户登录https://console.developers.google.com/

启动一个项目,启用gmailapi并为已安装的应用程序创建一个新的客户端id。位于https://developers.google.com/api-client-library/python/auth/installed-app#creatingcred的指令

单击“下载JSON”按钮,将此文件保存到公众无法访问的位置(因此可能不在代码库中)。在

第2步-获取googleoauth2 Python工具

https://code.google.com/p/google-mail-oauth2-tools/wiki/OAuth2DotPyRunThrough下载oauth2.py脚本

第3步-获取授权URL

使用步骤2中的脚本获取一个允许您授权Google项目的URL。在

在终端:

python oauth2.py user={myaccount@gmail.com} client_id={your client_id from the json file} client_secret={your client_secret from the json file} generate_oauth2_token

步骤4获取授权码

将步骤3中的URL粘贴到浏览器中,然后单击“accept”按钮。在

从网页复制代码。在

将代码粘贴到终端并按enter键。您将获得:

 To authorize token, visit this url and follow the directions:   https://accounts.google.com/o/oauth2/auth?client_id{...}
 Enter verification code: {...}
 Refresh Token: {...}
 Access Token: {...}
 Access Token Expiration Seconds: 3600

第5步-保存刷新令牌

从终端复制刷新令牌并将其保存到某个位置。在本例中,我将其保存到一个json格式的文本文件中,并使用键“Refresh Token”。但它也可以保存到私人数据库中。在

确保刷新令牌不能被公众访问!在

第6步-制作扭曲的验证器

下面是一个OAuth2验证器的工作示例。它需要步骤2中的oauth2.py脚本。在

^{pr2}$

步骤7-注册协议的authenticator

在IMAP4ClientFactory中:

    def buildProtocol(self, addr):
        p = self.protocol(self.ctx)
        p.factory = self
        x = GmailOAuthAuthenticator(self.reactor)
        p.registerAuthenticator(x)
        return p

步骤8-使用访问令牌进行身份验证

不要使用“login”,而是获取访问令牌(如果需要),然后使用authenticate。在

更改问题中的示例代码:

    @defer.inlineCallbacks
    def serverGreeting(self, caps):
        # log in
        try:
            # the line below no longer works for gmail
            # yield self.login(mailuser, mailpass)
            if GmailOAuthAuthenticator.authName in self.authenticators:
                yield self.authenticators[AriGmailOAuthAuthenticator.authName].getToken()

            yield self.authenticate("")

            try:
                yield self.uponAuthentication()
            except Exception as e:
                uponFail(e, "uponAuthentication")
        except Exception as e:
            uponFail(e, "logging in")

相关问题 更多 >