2010-04-08 39 views
14

Tôi đang phát triển một ứng dụng web sẽ gửi email thay mặt cho người dùng đã đăng nhập.Cách triển khai API OAuth của Gmail để gửi email (đặc biệt qua SMTP)?

Tôi đang cố sử dụng giao thức Gmail OAuth mới được công bố mô tả here để gửi các email này thông qua tài khoản Gmail của người dùng (tốt nhất là sử dụng SMTP thay vì IMAP, nhưng tôi rất dễ). Tuy nhiên, mã PHP mẫu cho tôi một vài vấn đề.

  1. Tất cả mã mẫu đều dựa trên IMAP chứ không phải SMTP. Tại sao "hỗ trợ" giao thức SMTP nếu bạn không cho mọi người biết cách sử dụng nó?
  2. Mã mẫu cung cấp cho tôi một lỗi nghiêm trọng từ một ngoại lệ Zend chưa được thực hiện - nó không thể tìm thấy thư mục "INBOX".

Fatal error: Uncaught exception 'Zend_Mail_Storage_Exception' with message 'cannot change folder, maybe it does not exist' in path\to\xoauth-php-samples\Zend\Mail\Storage\Imap.php:467 Stack trace: #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} Next exception 'Zend_Mail_Storage_Exception' with message 'cannot select INBOX, is this a valid transport?' in path\to\xoauth-php-samples\Zend\Mail\Storage\Imap.php:254 Stack trace: #0 path\to\xoauth-php-samples\three-legged.php(184): Zend_Mail_Storage_Imap->__construct(Object(Zend_Mail_Protocol_Imap)) #1 {main} in path\to\xoauth-php-samples\Zend\Mail\Storage\Imap.php on line 254

tôi đã xác minh rằng tôi nhận được OAuth tốt mã thông báo lại, tôi chỉ không biết làm thế nào để thực hiện giao dịch email thực tế xảy ra. Giao thức này vẫn còn khá mới mẻ, do đó, không có nhiều tài liệu cộng đồng không chính thức về nó ở đó, và các tài liệu chính thức là những thứ khô ráo vô ích về RFC SMTP. Vì vậy, nếu có ai có thể giúp điều này xảy ra, tôi rất cảm kích điều đó.

Lưu ý: Tôi đã có thể kết nối với máy chủ SMTP của Gmail qua SSL và gửi thành công email, miễn là người dùng đã cấp cho ứng dụng của tôi tên người dùng và mật khẩu Gmail của họ. Tôi muốn tránh phương pháp này, bởi vì nó khuyến khích người dùng lừa đảo và bảo mật không chấp nhận nó. Câu hỏi này không phải là về điều đó.

+0

Vì tôi mới, bộ lọc spam của Stack Overflow đã khiến tôi đưa ra các liên kết tới thông báo Gmail OAuth (http://googlecode.blogspot.com/2010/03/oauth-access-to-imapsmtp-in-gmail .html) và mã mẫu (http://code.google.com/p/google-mail-xoauth-tools/wiki/PhpSampleCode). –

+0

bạn có thể làm cho một ứng dụng web gửi email bằng cách sử dụng gmail thông qua javascript một mình. Giống như yêu cầu máy chủ gmail gửi cho người dùng. –

Trả lời

2

Bạn có đang sử dụng tài khoản Google Apps không?

Khi chuyển hướng đến URL mã thông báo OAuthAuthorize, tôi đã chỉ định nhầm hd = mặc định. Điều này cho điểm cuối OAuth cấp phép mã thông báo cho tài khoản Google chuẩn và nó KHÔNG hoạt động với Google Apps.

Vì vậy, trong ba legged.php, thay thế dòng nói rằng:

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

với

$consumer->redirect(); 

Và tất cả mọi thứ nên fine-- bạn nên được yêu cầu chọn giữa người tiêu dùng của bạn và tài khoản Google Apps nếu đăng nhập bằng cả hai.

Hy vọng điều này sẽ giúp-- Tôi sẽ vá mã để khắc phục sự cố này.

Chúc mừng, -Ryan

#

Re sử dụng SMTP-- Tôi đã không nhận này hoàn toàn cùng nhau nhưng trong một cách mà là tài liệu well-- nhưng đây là những điều cơ bản.

1) Tạo Zend/Mail/Protocol/Smtp/Auth/Xoauth.php, nơi mà các phương pháp auth() là khá đơn giản:

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

2) Tạo $ initClientRequest hơi khác nhau, như những thay đổi URL cho SMTP so với IMAP 3) Gửi mail như sau:

// 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); 

Tôi sẽ cố gắng tạo một tài liệu nào đó tốt hơn-- không yêu cầu tạo các lớp trong không gian tên của Zend, nhưng có lẽ nó cũng yêu cầu mở rộng Zend_Mail_Transport_Smtp vì cách _sendMail() được viết trong đó để tải các lớp auth chỉ từ gói Zend_Mail_Protocol_Smtp_Auth_ * ''

+0

Ryan, cảm ơn thông tin. Tôi sẽ thử chạy mã này và xem những gì tôi nghĩ ra. Tôi đánh giá cao những nỗ lực của bạn ở đây. Tôi đã không cố gắng gửi email thông qua tài khoản Google Apps, chỉ cần Gmail thuần chay cũ. –

+0

Tôi đang cố gắng tự làm việc này. Tôi không hiểu dòng này: $ smtpInitClientRequestEncoded = getXoauthClientRequest ($ smtpUrl, $ accessToken); Tôi nhận được ở đâu hoặc làm cách nào để tạo getXoauthClientRequest? – PaulM

4

Tôi đang sử dụng tài khoản Google Apps và cố tạo ứng dụng cho phép người dùng của tôi gửi thư qua SMTP thông qua ủy quyền Oauth mới. Tôi đã có thể làm cho nó hoạt động bằng cách sử dụng một số thông tin về cuộc thảo luận này. Tuy nhiên, tôi nghĩ rằng tôi nên làm rõ một vài điều mà tôi vấp phải ...

1) Khuôn khổ Zend cho SMTP dường như tự động tìm trong thư mục Zend/Mail/Protocol/Smtp/Auth cho tên tệp .php in trường hợp này "Xoauth.php" không thường tồn tại trong Zend trừ khi bạn tạo nó. Tôi đã có thể làm điều này thành công bằng cách sao chép tệp Login.php hiện có sang Xoauth.php và sửa đổi nó một chút với các đề xuất được thực hiện trên trang web này.

này was very helpful nhưng nó chỉ là một phần của tập tin Xoauth.php (Chỉnh sửa một bản sao của login.php và bạn sẽ thấy một khu vực tương đương):

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

2) Lưu ý rằng bạn nên chắc chắn có Zend trên include_path PHP ngay cả khi bạn tham chiếu nó trực tiếp trong PHP vì nó có thể cố gắng tham chiếu chính nó với tệp Loader.php của nó mà không sử dụng một đường dẫn rõ ràng.

3) Bên cạnh việc xóa các hàm IMAP rõ ràng và thay thế chúng bằng các hàm SMTP tương đương, tôi không cần phải thay đổi mã từ các mẫu Google OAuth cho PHP. Tôi đã phải bao gồm các tập tin Zend/Mail.php để gửi email và thêm mã cần thiết để thực sự gửi email cho thử nghiệm để làm việc.

+0

Điều này thật tuyệt vời. Tôi đã nhận được chính xác các lỗi tương tự mà Curtis đã nhận được, và làm những gì bạn đã đề cập trong bước 1 làm cho nó hoạt động! –

Các vấn đề liên quan