使用Ruby为Gmail IMAP访问生成SASL XOAUTH2客户端响应

时间:2013-06-05 17:07:31

标签: ruby oauth gmail imap sasl

我正在尝试使用Ruby中的XOAUTH2通过IMAP访问我的Gmail电子邮件。

我通过使用OAuth 2.0和oauth2 gem进行身份验证,成功生成了访问令牌(和刷新令牌)。我将使用gmail_xoauth通过IMAP访问Gmail。所以我现在需要根据the Gmail XOAuth2 docs生成SASL初始客户端响应:

The SASL XOAUTH2 initial client response has the following format:  

    base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")

using the base64 encoding mechanism defined in RFC 4648.
^A represents a Control+A (\001).

我不清楚我是如何在字符串中表示“Control + A”的。我只是使用^A

key = Base64.encode64("user=#{email}^Aauth=Bearer #{access_token_obj.token}^A^A")

This python script使用\1代替^A。我也试过\001。无论我尝试什么,在用结果验证(用irb)时我得到:

>> imap = Net::IMAP.new('imap.gmail.com', 993, usessl=true, certs=nil, verify=false)
>> imap.authenticate('XOAUTH2', email, key)
OpenSSL::SSL::SSLError: SSL_write:: bad write retry

这个错误可能完全不相关,但我不相信我尝试的任何选项都是正确的。

1 个答案:

答案 0 :(得分:4)

终于想通了......我根本不需要做Base64编码步骤!

gmail_xoauth adds the XOAUTH authenticatorNet::IMAP本身。我意识到这只是期望来自Google的未编码access_token,而不是更长的Base64编码字符串。

所以,如果:

email = `fredbloggstest@gmail.com`
# The result of the OAuth2 dance (as well as a refresh_token):
access_token = 'ya13.AHES6Y3F54_5fAoz_8VuG-7pzQAo3R0_ukt7dhfgRnJh41Q'

然后我没有Base64编码任何东西。我只是这样做:

imap = Net::IMAP.new('imap.gmail.com', 993, usessl=true, certs=nil, verify=false)
imap.authenticate('XOAUTH2', email, access_token)

我回来了:

#<struct Net::IMAP::TaggedResponse tag="RUBY0001", name="OK", data=#<struct Net::IMAP::ResponseText code=nil, text="fredbloggstest@gmail.com Fred Bloggs authenticated (Success)">, raw_data="RUBY0001 OK fredbloggstest@gmail.com Fred Bloggs authenticated (Success)\r\n">

(作为奖励,this is a handy Ruby script从OAuth舞蹈中获取access_token。)