Как реализовать API Gmail OAuth для отправки электронной почты (особенно через SMTP)?

Я разрабатываю веб-приложение, которое будет отправлять электронные письма от имени зарегистрированного пользователя.

Я пытаюсь использовать новый протокол Gmail OAuth, описанный здесь, чтобы отправить эти письма через учетную запись пользователя Gmail (предпочтительно используя SMTP, а чем IMAP, но мне легко). Однако пример кода PHP дает мне несколько проблем.

  • Все примеры кода основаны на IMAP, а не на SMTP. Зачем "поддерживать" протокол SMTP, если вы не собираетесь показывать людям, как его использовать?
  • Образец кода дает мне фатальную ошибку из неперехваченного исключения Zend - он не может найти папку "INBOX".

Неустранимая ошибка: исключение "Zend_Mail_Storage_Exception" с сообщением "невозможно изменить папку, возможно, она не существует" в пути \to\xoauth-php-samples\Zend\Mail\Storage\Imap.php: 467 Трассировка стека: 0 путь \to\xoauth-php-samples\Zend\Mail\Storage\Imap.php(248): Zend_Mail_Storage_Imap- > selectFolder ('INBOX') # 1 путь \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, это действительный транспорт?" в пути \to\xoauth-php-samples\Zend\Mail\Storage\Imap.php: 254 Трассировка стека: путь # 0\to\xoauth-php-samples\three-legged.php(184): Zend_Mail_Storage_Imap → __ construct (Object (Zend_Mail_Protocol_Imap)) # 1 {main} в пути \to\xoauth-php-samples\Zend\Mail\Storage\Imap.php в строке 254

Я проверил, что я получаю хорошие токены OAuth, я просто не знаю, как сделать реальную транзакцию электронной почты. Этот протокол по-прежнему является довольно новым, поэтому там не так много неофициальной документации сообщества, и официальные документы - бесполезно сухие вещи о SMTP RFC. Поэтому, если кто-то может помочь в этом, я бы очень признателен.

Примечание. Я уже смог подключиться к SMTP-серверу Gmail через SSL и успешно отправить электронное письмо при условии, что пользователь предоставил моему приложению свое имя пользователя и пароль Gmail. Я бы хотел избежать этого метода, потому что он поощряет пользователей фишинга и безопасности, которые не будут его принимать. Этот вопрос не об этом.

Ответ 1

Я использую аккаунт Google Apps и пытаюсь создать приложение, которое позволяет моим пользователям отправлять почту через SMTP с помощью новой авторизации Oauth. Я смог заставить его работать, используя некоторую информацию об этом обсуждении. Однако, я думаю, я должен прояснить пару вещей, которые я наткнулся на...

1) Структура Zend для SMTP, по-видимому, автоматически просматривается в папке 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) Обратите внимание, что вы обязательно должны иметь Zend на PHP include_path, даже если ссылаетесь на него напрямую на PHP, потому что он может попытаться ссылаться на свой файл Loader.php, не используя явный путь.

3) Помимо удаления очевидных функций IMAP и замены их эквивалентными функциями SMTP мне не нужно было менять код из образцов Google OAuth для PHP. Я должен был включить Zend/Mail.php файл для отправки электронной почты и добавления кода, необходимого для фактической отправки электронной почты для проверки на работу.

Ответ 2

Используете ли вы аккаунт Google Apps?

При перенаправлении на URL-адрес токена OAuthAuthorize я ошибочно указал hd = default. Это указывает конечной точке OAuth разрешить токен стандартной учетной записи Google и не работает с Google Apps.

Итак, в three-legged.php замените строку, которая говорит:

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

с

$consumer->redirect();

И все должно быть в порядке - вас попросят выбрать между вашим потребителем и аккаунтом Google Apps, если вы вошли в систему с обоими.

Надеюсь, что это поможет... Я исправлю код, чтобы исправить эту проблему.

Cheers, -Ryan

#

Re, используя 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 несколько иначе, так как URL-адрес изменится для SMTP по сравнению с IMAP 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() auth только из пакета Zend_Mail_Protocol_Smtp_Auth_ * '