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

Cur*_*bby 14 php api gmail smtp oauth

我正在开发一个Web应用程序,它将代表已登录的用户发送电子邮件.

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

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

致命错误:未捕获的异常'Zend_Mail_Storage_Exception',消息'无法更改文件夹,也许它不存在'在path\to\xoauth-php-samples\Zend\Mail\Storage\Imap.php:467堆栈跟踪:#0 path \到\ 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用户名和密码.我想避免这种方法,因为它鼓励网络钓鱼,安全意识的用户不会接受它.这个问题与此无关.

use*_*700 2

您使用的是 Google Apps 帐户吗?

当重定向到 OAuthAuthorize 令牌 URL 时,我错误地指定了 hd=default。这告诉 OAuth 端点为标准 Google 帐户授权令牌,但它不适用于Google Apps。

因此,在三足.php 中,替换以下行:

$consumer->redirect(array('hd' => 'default'));
Run Code Online (Sandbox Code Playgroud)

$consumer->redirect();
Run Code Online (Sandbox Code Playgroud)

一切都应该没问题 - 如果您同时登录了您的消费者帐户和 Google Apps 帐户,系统会要求您在这两个帐户之间进行选择。

希望这有帮助——我将修补代码来解决这个问题。

干杯,-瑞安

#

重新使用 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;
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

我将尝试创建更好的文档记录——它不需要在 Zend '命名空间'中创建类,但它可能也需要扩展 Zend_Mail_Transport_Smtp,因为 _sendMail() 的写入方式仅用于加载身份验证类来自 Zend_Mail_Protocol_Smtp_Auth_* '包'