Cakephp 3 尝试使用 gmail 发送电子邮件时出错

Posted

技术标签:

【中文标题】Cakephp 3 尝试使用 gmail 发送电子邮件时出错【英文标题】:Cakephp 3 error trying to send email with gmail 【发布时间】:2015-12-21 07:58:56 【问题描述】:

我正在尝试使用 Gmail 发送验证电子邮件,但收到此错误:

stream_socket_client():SSL 操作失败,代码为 1。OpenSSL 错误消息:错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 stream_socket_client():启用加密失败 stream_socket_client():无法连接到 ssl://smtp.gmail.com:465 (未知错误)

我遵循了Configuring Transports 指南。

Email::configTransport('gmail', [
  'host' => 'ssl://smtp.gmail.com',
  //'host' => 'smtp.gmail.com',
  'port' => 465,
  'username' => 'user@gmail.com',
  'password' => 'password',
  'className' => 'Smtp',
  'log'=>true,
  //'tls' => true
]); 

$correo = new Email();
$correo
  ->transport('gmail')
  ->template('registro_exito')
  ->emailFormat('html')
  ->to('email@gmail.com')
  ->from('another_email@gmail.com')
  ->viewVars([
    'nombre_sitio_secundario'=>$nombre_sitio_secundario,
    'usuario_id'=>$usuario_id,
    'token'=>$token
  ])
  ->send(); 

这是完整的错误日志:

2015-09-24 20:09:39 Error: [Cake\Network\Exception\SocketException] stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
stream_socket_client(): Failed to enable crypto
stream_socket_client(): unable to connect to ssl://smtp.gmail.com:465 (Unknown error)
Request URL: /faindit/usuarios/registro
Stack Trace:
#0 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Network\Email\SmtpTransport.php(204): Cake\Network\Socket->connect()
#1 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Network\Email\SmtpTransport.php(159): Cake\Network\Email\SmtpTransport->_connect()
#2 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Network\Email\Email.php(1301): Cake\Network\Email\SmtpTransport->send(Object(Cake\Network\Email\Email))
#3 C:\xampp\htdocs\faindit\src\Controller\Component\CorreoComponent.php(65): Cake\Network\Email\Email->send()
#4 C:\xampp\htdocs\faindit\src\Controller\UsuariosController.php(14): App\Controller\Component\CorreoComponent->registroExito(1, 'something@gm...')
#5 [internal function]: App\Controller\UsuariosController->registro()
#6 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Controller\Controller.php(411): call_user_func_array(Array, Array)
#7 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(114): Cake\Controller\Controller->invokeAction()
#8 C:\xampp\htdocs\faindit\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\UsuariosController))
#9 C:\xampp\htdocs\faindit\webroot\index.php(37): Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#10 main

值得一提的是,在 php 上启用了 openssl es,而且我还在 Gmail 配置中启用了“访问不太安全的应用程序”。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

好的,我发现了“错误”。实际上代码很好,问题在于 php 5.6 中的OpenSSL 默认情况下会验证每个加密连接但我的本地 Lampp 不计入 ssl 证书,这会导致错误。

解决办法是避免验证,所以configTransport代码是这样的:

Email::configTransport('gmail', [
  'host' => 'ssl://smtp.gmail.com',
  'port' => 465,
  'username' => 'user@gmail.com',
  'password' => 'password',
  'className' => 'Smtp',
  'log' => true,
  'context' => [
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true
    ]
  ]
]); 

我将PHPMailer answer 作为参考,但知道如何将其应用于 Cakephp3 有点挑战。

希望这些信息对其他人有所帮助。

【讨论】:

太棒了。谢谢! 开发中只能在本地避免验证。它必须在生产中处于活动状态。【参考方案2】:
    Send a verification email using gmail in CakePhp 3 

    Follow these steps to send verification code using gmail

    1. open your your project/config/app.php

    2. In your app.php, replace(hide) this code 
         'EmailTransport' => [
            'default' => [
                'className' => 'Mail',
                // The following keys are used in SMTP transports
                'host' => 'localhost',
                'port' => 25,
                'timeout' => 30,
                'username' => 'user',
                'password' => 'secret',
                'client' => null,
                'tls' => null,
                'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
          ],

     write this code in your app.php

       'EmailTransport' => [
            'default' => [
                'className' => 'Mail',
                // The following keys are used in SMTP transports
                'host' => 'localhost',
                'port' => 25,
                'timeout' => 30,
                'username' => 'user',
                'password' => 'secret',
                'client' => null,
                'tls' => null,
                'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
            ],
            'gmail'=> [
              'host' => 'ssl://smtp.gmail.com',
              'port' => 465,
              'username' => 'abc@gmail.com',  //your gmail address
              'password' => 'abcd123',        //your gmail password
              'className' => 'Smtp',
              'log' => true,
              'context' => [
                'ssl' => [
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                ]
              ]
            ],
        ],

    3. Now open your Controller file and add this code
        use Cake\Mailer\Email;
        use Cake\Network\Exception\SocketException;


   4. Write this code on function of your controller which is in used
        $msg="Your Password is generate";
           $email = new Email('default');
           $email
                ->transport('gmail')
                ->from(['abcx.com' => 'abcx.com'])
                ->to($to)
                ->subject($subject)
                 ->emailFormat('html')
                ->viewVars(array('msg' => $msg))
                ->send($msg);

     now you can send email from your controller by using this code




    5. if this error generate(SMTP server did not accept the password.) then do this process


    i.> If the tips above didn't help, visit https://www.google.com/accounts/DisplayUnlockCaptcha and follow the steps on the page.

    ii.> Allow access to your Google account

      As a security precaution, Google may require you to complete this  additional step when signing into a new device or application.

    To allow access, click the Continue button below.




    iii.> Account access enabled

    Please try signing in to your Google account again from your new device or application.

    6. run your application

【讨论】:

以上是关于Cakephp 3 尝试使用 gmail 发送电子邮件时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 gmail 从本地主机发送电子邮件

CakePHP / 通用 HTML 电子邮件

CakePHP 发送电子邮件 - LAMPP

尝试使用 Flask 和 Gmail 发送电子邮件时出错

cakephp 电子邮件组件 phpmailer

尝试在 Java 中使用 Gmail API 发送电子邮件时出错