如何实施Gmail OAuth API以发送电子邮件(特别是通过SMTP)?

时间:2010-04-08 19:09:36

标签: php api smtp oauth gmail

我正在开发一个代表登录用户发送电子邮件的Web应用程序。

我正在尝试使用已宣布的新版Gmail OAuth协议here通过用户的Gmail帐户发送这些电子邮件(最好使用SMTP而不是IMAP,但我很容易)。但是,示例PHP代码给我带来了一些问题。

  1. 所有示例代码都基于IMAP,而不是SMTP。如果您不打算向人们展示如何使用它,为什么要“支持”SMTP协议呢?
  2. 示例代码给出了一个未被捕获的Zend异常的致命错误 - 它无法找到“INBOX”文件夹。
  3.   

    致命错误:未捕获的异常'Zend_Mail_Storage_Exception',消息'无法更改文件夹,可能它不存在'在path \ to \ xoauth-php-samples \ Zend \ Mail \ Storage \ Imap.php:467堆栈跟踪:# 0 path \ to \ xoauth-php-samples \ Zend \ Mail \ Storage \ Imap.php(248):Zend_Mail_Storage_Imap-> selectFolder('INBOX')#1 path \ to \ xoauth-php-samples \ three-legged。 php(184):Zend_Mail_Storage_Imap-> __ construct(Object(Zend_Mail_Protocol_Imap))#2 {main}下一个异常'Zend_Mail_Storage_Exception',消息'无法选择INBOX,这是一个有效的传输吗?'在path \ to \ xoauth-php-samples \ Zend \ Mail \ Storage \ Imap.php:254堆栈跟踪:#0 path \ to \ xoauth-php-samples \ three-legged.php(184):Zend_Mail_Storage_Imap-> __construct(对象(Zend_Mail_Protocol_Imap))路径中的#1 {main}到第254行的\ xoauth-php-samples \ Zend \ Mail \ Storage \ Imap.php

    我已经确认我收到了很好的OAuth令牌,我只是不知道如何让实际的电子邮件交易发生。这个协议仍然是新的,因此没有太多关于它的非官方社区文档,官方文档对于SMTP RFC来说是无用的。因此,如果有人能帮助实现这一目标,我将非常感激。

    注意:我已经能够通过SSL连接到Gmail的SMTP服务器并成功发送电子邮件,前提是用户已向我的应用程序提供了他/她的Gmail用户名和密码。我想避免这种方法,因为它鼓励网络钓鱼,安全意识的用户不会接受它。这个问题与此无关。

2 个答案:

答案 0 :(得分:4)

我正在使用Google Apps帐户并尝试创建一个应用程序,允许我的用户通过新的Oauth授权通过SMTP发送邮件。我能够使用这个讨论中的一些信息让它工作。但是,我想我应该澄清一些我偶然发现的事情......

1)用于SMTP的Zend框架显然会自动在Zend / Mail / Protocol / Smtp / Auth文件夹中查找文件名.php,在本例中为“Xoauth.php”,除非您创建它,否则它通常不存在于Zend中。我能够通过将现有的Login.php文件复制到Xoauth.php并使用此网页上的建议稍微修改它来成功地完成此任务。

这非常有用,但它只是Xoauth.php文件的一部分(编辑login.php的副本,你会看到一个等效的区域):

// Ensure AUTH has not already been initiated.
parent::auth();
$this->_send('AUTH XOAUTH ' . $this->_xoauth_request);
$this->_expect(235);
$this->_auth = true;

2)请注意,即使您直接在PHP中引用它,您也应该在PHP include_path上使用Zend,因为它可能会尝试使用其Loader.php文件引用自身而不使用显式路径。

3)除了删除明显的IMAP功能并使用等效的SMTP功能替换它们之外,我不需要更改PHP的Google OAuth示例中的代码。我必须包含Zend / Mail.php文件,以便发送电子邮件并添加实际发送电子邮件以使测试工作所需的代码。

答案 1 :(得分:2)

您使用的是Google Apps帐户吗?

重定向到OAuthAuthorize令牌网址时,我错误地指定了hd = default。这告诉OAuth端点授权标准Google帐户的令牌,并且 NOT 使用Google Apps。

因此,在three-legged.php中,替换说:

的行
$consumer->redirect(array('hd' => 'default'));

$consumer->redirect();

一切都应该没问题 - 如果同时登录,则应该要求您在消费者和Google Apps帐户之间进行选择。

希望这会有所帮助 - 我将修补代码以解决此问题。

干杯, -Ryan

重新使用SMTP--我还没有以完全记录的方式将它完全整合在一起 - 但这是基础知识。

1)创建Zend / Mail / Protocol / Smtp / Auth / Xoauth.php,其中auth()方法相当简单:

// Ensure AUTH has not already been initiated.
parent::auth();
$this->_send('AUTH XOAUTH ' . $this->_xoauth_request);
$this->_expect(235);
$this->_auth = true;

2)生成$ initClientRequest略有不同,因为SMTP与IMAP的URL发生了变化 3)发送如下邮件:

  // where getXoauthClientRequest abstracts out line 116-165 in existing three-legged.php
  $smtpInitClientRequestEncoded = getXoauthClientRequest($smtpUrl, $accessToken);

  $config = array('ssl' => 'ssl',
                  'port' => '465',
                  'auth' => 'xoauth',
                  'xoauth_request' => $smtpInitClientRequestEncoded);

  $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
  $mail = new Zend_Mail();
  $mail->setBodyText('This is the text of the mail.');
  $mail->setFrom($email_address, 'Some Sender');
  $mail->addTo($email_address, 'Some Recipient');
  $mail->setSubject('TestSubject');
  $mail->send($transport);

我将尝试创建更好的文档 - 这不需要在Zend'命名空间中创建类,但它可能还需要扩展Zend_Mail_Transport_Smtp,因为_sendMail()的编写方式在那里加载仅来自Zend_Mail_Protocol_Smtp_Auth_ *'package'

的auth类