Usando Gmail con OAUTH2 en Linux y ESP8266

Una de las tareas que temo es configurar un servidor web para enviar correctamente el correo electrónico a través de Gmail. La forma más sencilla de enviar correos electrónicos es SMTP, y existen varios scripts que proporcionan un método simple para enviar correo con una configuración mínima. Incluso hay PHP mail(), aunque es menos confiable.

Gmail requiere que OAUTH2 se autentique y comparta datos de usuario, lo que tiene la principal ventaja de no requerir que almacene su nombre de usuario y contraseña en la aplicación que requiere acceso a su cuenta. Aunque tienen una opción "Permitir programas menos seguros", que permite el acceso SMTP a productos heredados como Microsoft Outlook, simplemente no parece el camino correcto a seguir. Google documenta cómo interactuar con su API con OAUTH2, entonces, ¿por qué no usar eso en lugar de poner mi nombre de usuario y contraseña en texto sin cifrar en un conjunto de prototipos y scripts de prueba?

Esos son los pensamientos que pasan por mi cabeza cada vez que se trata de un proyecto, y cada vez que de alguna manera olvidé los pasos para hacerlo, también olvidé anotarlo y finalmente pierdo el tiempo suficiente por mi propia estupidez. Como penitencia, decidí documentar el proceso y compartirlo con todos ustedes, y luego también ejecutarlo en una placa ESP8266 con el entorno de desarrollo Arduino.

Antes de continuar, ahora sería un buen momento para una actualización no técnica sobre cómo funciona OAUTH. Las principales diferencias entre OAUTH y OAUTH2 son que este último requiere HTTPS y caducan los tokens de acceso que permiten a un programa utilizar servicios específicos en una cuenta de usuario.

Para usar Gmail con OAUTH2, tendremos que comenzar con cinco cosas: una aplicación registrada en las API de Google, su ID de cliente y secreto de cliente, una computadora que ejecute LAMP (el VPS por hora funciona bien aquí) y un nombre de dominio.

Registrar una aplicación usando la API de Google es fácil. Vaya a la consola de la API de Google, inicie sesión, cree un nuevo proyecto e introdúzcalo. Habilite la API de Gmail; debe ofrecerse en la primera página.

Con el proyecto creado y la API de Gmail habilitada, el panel debería verse así

Luego haga clic en 'certificados' en la barra lateral, cree certificados y finalmente 'cree ID de cliente OAUTH'. Antes de que pueda continuar, debe crear una pantalla de consentimiento. La única entrada que realmente debe completar ahora es "Nombre del producto mostrado a los usuarios".

Después de guardar este formulario, seleccione 'Solicitud en línea' como su tipo de solicitud. Tenga en cuenta el campo llamado 'URI de redireccionamiento autorizado', volveremos a él más adelante. Es importante que esté configurado correctamente para que podamos recibir una señal de actualización más adelante en este proceso.

Por ahora, simplemente presione "Crear". Aparecerá una ventana emergente que contiene su ID de cliente y su secreto de cliente. Los necesitará pronto, por lo que es mejor copiarlos / pegarlos en un archivo local en su computadora por ahora.

Luego usaremos esos dos datos para solicitar una señal de acceso y una señal de actualización. También podemos lograr dos cosas a la vez aquí instalando el popular remitente de correo electrónico PHP llamado PHPMailer en nuestro servidor web. Incluye una herramienta para solicitar un signo de acceso / actualización OAUTH2 y también enviar fácilmente un correo electrónico de prueba rápido. Para instalarlo usaremos la herramienta de gestión de dependencias PHP Composer:

$sudo apt-get install composer

Luego tenemos que navegar a nuestro directorio accesible en la web, en mi caso /var/www/htmle instale algunos scripts PHP. Tenga en cuenta que esto no debe hacerse como root, así que cree otro usuario si es necesario y déle acceso al directorio:

$composer require phpmailer/phpmailer
$composer require league/oauth2-client
$composer require league/oauth2-google

Ahora entra en la carpeta vendor/phpmailer/phpmailer. Habrá un guión llamado get_oauth_token.php. Mueva este script hacia arriba tres carpetas en la carpeta desde la que acaba de ejecutar los comandos 'compositor'. La ubicación de este script, visto desde el sitio web, debe ingresarse en el campo 'URI de redireccionamiento autorizado' de la API de Google que vimos anteriormente. En este caso sería tan https://mydomain.com/get_oauth_token.php. Las direcciones IP públicas no funcionarán, por lo que un nombre de dominio que se muestre a su servidor web es un requisito.

Ahora abierto get_oauth_token.php en un editor de texto y pegue su ID de cliente y su secreto de cliente cuando sea necesario. No intente ejecutar el script localmente, fallará. Abra un navegador web en cualquier computadora y vaya a la URL que ingresó como 'URI de redireccionamiento autorizado'. Luego, seleccione Google de la lista de servicios de correo electrónico; en ese momento, si funciona, se le pedirá que inicie sesión y luego autorice la aplicación no confirmada, en "Avanzado" debajo del aviso de advertencia, y finalmente recibirá una señal de actualización. Si por alguna razón está accediendo a un personaje solo por alguna razón, deberá editar el guión para repetirlo.

Si eso no funcionó, hay dos razones comunes: un URI de redireccionamiento incorrecto o la secuencia de comandos no puede encontrar sus dependencias. En el primer caso, el mensaje de error de Google le indicará la URL del script tal como la ve, y puede usar esa información para actualizar el URI de redireccionamiento en la Consola API de Google para resolver el problema. Para este último, verifique su error de Apache, probablemente ubicado en /var/log/apache2/error.log, para ver qué dependencia no se encuentra. Puede ver algo como esto:

PHP Warning: require(vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/mydomain/get_oauth_token.php on line 59, referer: http://mydomain.com/get_oauth_token.php

Si recibió su refrescante signo, enhorabuena: se acabó la parte dolorosa. Simplemente puede ir a la página de PHPMailer Github y completar su ejemplo de OAUTH2 (gmail_xoauth.phps), y debería funcionar. Si solo necesita enviar correo del proyecto a través de su VPS, está más o menos listo para pasar a partes más interesantes de su proyecto:

$email="[email protected]";
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret="RANDOMCHARS-----lGyjPcRtvP";
//Obtained by configuring and running get_oauth_token.php
//after setting up an app in Google Developer Console.
$refreshToken = 'RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0';

Recuerde limpiar cualquier script innecesario que contenga su signo de actualización y otros datos confidenciales antes de continuar.

ESP8266: No necesitamos servidores malolientes

Ahora bien, si quisiéramos usar estos caracteres para enviar correos electrónicos directamente desde un proyecto en una Raspberry Pi sin la necesidad de un servidor en el medio. Resulta que una vez que tenemos la identificación del cliente, el secreto del cliente y el letrero de actualización, ya no necesitamos el servidor y el nombre de dominio que usamos hasta ahora, y una aplicación de correo, como PHPMailer, se puede instalar en una computadora en cualquier lugar con Internet. acceso, siempre que esté configurado con esos valores.

Las cosas se complican un poco más cuando intentamos hacer esto con ESP8266. OAUTH2 requiere que usemos SSL, y los tokens de acceso caducan con regularidad y deben actualizarse. por suerte [jalmeroth] generosamente escribió una prueba de concepto y la publicó en GitHub. Si se le proporciona una señal de acceso, puede acceder a su cuenta de Gmail y usarla para enviar correo electrónico. También puede actualizar / obtener datos directamente de Hojas de cálculo de Google, pero no lo he probado. Sin embargo, si el token de acceso expiraba, no podía detectarlo, a pesar de que incluía un código de función para solicitar un nuevo token, pero no analizarlo y usarlo.

Tratando de agregar el funcionamiento de ese concepto de prueba, eliminé el proyecto e hice algunos cambios. Primero, cambié a un orden de operaciones en el código para verificar si la señal de acceso actual era válida antes de hacer cualquier otra cosa. En segundo lugar, la API de Google respondió con "400 solicitudes incorrectas" si la señal de acceso no era válida, y todas las respuestas excepto "200 buenas" fueron filtradas por el código. Finalmente, escribí algunos analizadores JSON que verifican el motivo de la "400 solicitud incorrecta" y extraen y usan el token de acceso devuelto por la API de Google cuando se solicita una nueva.

Funciona, pero es poco confiable, lo que no es sorprendente considerando que nunca antes había usado la plataforma Arduino. Especialmente la huella digital SHA1 para la API de Google a menudo falla. Verificando desde mi máquina local, la huella digital SHA1 también varía entre dos firmas allí. Sería bastante fácil comprobar cualquiera de ellos, o simplemente seguir intentándolo, pero prefiero entender qué sucede primero. (¿Es solo un CDN o algo más?) O tal vez reescribiera toda la aplicación en Lua, donde soy más competente.

Un pequeño programa divertido creado en la parte superior fue poner un botón en mi oficina que envía un correo electrónico a mi teléfono. No quiero que la gente se comunique conmigo en esa dirección de correo electrónico de manera frívola, pero quiero saber de inmediato si alguien está esperando fuera de mi oficina. El gran botón rojo es para solicitudes normales, pero las solicitudes urgentes necesitan una opción de bloqueo. Si es urgente, es mejor ser interesante también.

Finalmente, ¿sabías que La-Tecnologia proporciona una API para acceder a la-tecnologia.io? Utiliza la autenticación OAUTH (no OAUTH2) más simple, por lo que debería ser más simple que la anterior que se puede implementar en el ESP8266. ¿Alguno de ustedes lo ha usado?

  • kevinmkessler dice:

    OAuth es tan complejo que sugeriría a la mayoría de las personas que solo desean enviar un correo electrónico desde un microcontrolador que creen una nueva cuenta de Gmail para sus juguetes, configuren el bit menos seguro y utilicen bibliotecas SMTP probadas y reales para eso. No veo una gran diferencia de seguridad entre tener que entregar un token secreto a su programa o nombre de usuario / contraseña.

    • ZAK dice:

      OAuth no es terriblemente complejo, el flujo de trabajo de OAuth 2 está diseñado para abordar integraciones en conjuntos completos de ecosistemas mientras el propietario de los datos mantiene el control de acceso a servicios individuales. Aunque no parece el más adecuado para su caso de uso, se adapta perfectamente a programas como servicio.

    • Clemens dice:

      La gran cantidad de pasos y el confuso ir y venir de oscuros ejes, fichas y secretos es exactamente la razón por la que a nadie le gusta ir por el camino "seguro" si lo elige. Parece tan ridículo emprender estos medios entrelazados para hacer algo tan básico como enviar un correo electrónico.

    • rocketboy001 dice:

      No quería engañar a una segunda cuenta y, de todos modos, no pude hacer que ESP enviara correos electrónicos de manera confiable a través de gmail directamente, incluso con la seguridad adicional desactivada. Entonces recordé que tenía un servidor Postfix local (expuesto solo a la LAN) que está configurado como retransmisor a Gmail. Debido a que está solo en la red, no tengo ni necesito TLS ni ninguna autenticación. Para que el ESP pueda conectarse a él sin problemas. Postfix luego se conecta a Gmail para transmitir los mensajes.

      Obviamente, no hay solución si está entregando el dispositivo a otra persona o no desea configurar un relé Postfix (en realidad, no es tan difícil). Pero para los dispositivos en su LAN no es una mala forma. SMTP2GO ofrece un servicio SMTP gratuito (más o menos) que no requiere TLS, pero obviamente no sería ideal si te preocupa la seguridad.

  • RoGeorge dice:

    ¿Cómo exactamente SMTP es menos confiable, y desde cuándo, y por qué me molestaría en vincularme desde otro proveedor, Gmail, solo por qué? Un ejemplo sería genial.

    • hli dice:

      Lea de nuevo. No es SMTP, que se ha llamado no confiable, sino 'mail ()' de PHP.

      • Jaime dice:

        La función de correo no es poco fiable. La función de correo funciona como se esperaba.

        La mayoría de las veces sucede que el servidor a través del cual las personas usan la función de correo no está configurado correctamente para enviar correo, o el DNS no está configurado correctamente para los registros MX y esto provoca el rechazo del correo. No tiene nada que ver con la función en sí. Usé de manera confiable la función de correo para el envío de correo básico desde 2003 hasta 2007 cuando comencé a usar SwiftMail.

        • Sean Boyce dice:

          Mi experiencia ha sido que los filtros de spam tienden a oponerse a [email protected] enviado por un servidor de correo electrónico en cualquier VPS en el mundo en desarrollo (donde vivo). Para ser claro, no estamos hablando de spam, solo cosas como formularios de contacto en páginas web, alertas generadas por algún sensor que alguien quiere específicamente o pruebas enviadas a mí por algún proyecto único.

          Entonces, pagar por Google Aps for Commerce a través de OAUTH2 (o SMTP si decide seguir esa ruta) me ofreció una mejor capacidad de entrega. Php mail () realmente tuvo problemas. Si está interesado en leer más sobre las cosas que puede tener, recuerdo que PHPMailer describió algunas de ellas en su documentación.

      • rubypanther dice:

        Para un cliente de lectura de gmail de GUI usé Ruby, Gtk2 e IMAP. La configuración SMTP es casi idéntica a la parte IMAP, por lo que debería ser bastante fácil.

        Es multiplataforma y funciona en bandeja. Escribí uno similar en 2002 para una publicación de Yahoo que usaba Perl.

        Tal vez el problema sea solo con PHP mail ()

        Lo que me gusta de usar IMAP / SMTP es que si quisiera cambiar a alojar mi propio correo electrónico, podría usar una configuración de servidor de correo electrónico normal y mantener el mismo cliente.

  • Bill Sussman dice:

    Si utiliza el servidor de correo electrónico de su ISP para salir, normalmente ni siquiera necesita autenticarse

  • Jaime dice:

    "Google documenta cómo interactuar con su API con OAUTH2, entonces, ¿por qué no usar eso en lugar de poner mi nombre de usuario y contraseña en texto sin formato en un conjunto de prototipos y scripts de prueba?"

    Porque la documentación de Google es una mierda. Está hinchado y, a menudo, es difícil de seguir.

    • Ø dice:

      Aquí están los productos y servicios de Google en general, aunque no hay cosas sin valor para el mínimo común denominador.

    • Sean Boyce dice:

      Sí, te lo concedo.

      Para ser justos, muchos productos excelentes que cambian rápidamente tienen una documentación terrible. Una frustración particular mía es la documentación de Facebook.

  • arre345 dice:

    Soy solo yo, o hay algo incorrecto en lo complejo que es ... solo para autenticarse con OAUTH.
    Eche un vistazo a los tutoriales rápidos que Google tiene en su página. cientos y cientos de líneas de código ... solo para iniciar sesión.
    Me falta el buen nombre de usuario y la contraseña.

    ¡Gracias por la edición!

    • Jaime dice:

      Sí, tengo que ocuparme de su documentación todos los días, y cada vez que lo necesito, quiero encontrar a la persona que los escribió y asfixiarlos ...

      Oauth es un animal complejo, la cuestión es que no pones nombres de usuario y contraseñas donde cualquiera pueda obtenerlos. Solo una identificación y secreto con permiso para acceder a lo que se necesita para la aplicación. Si alguien roba el secreto, puede revocarlo y crear uno nuevo sin tener que preocuparse si la mayor parte de su cuenta se ha visto comprometida porque perdió el acceso a su contraseña.

  • tour de lombok dice:

    Realmente cuando alguien no entiende más tarde, depende de otras personas
    ellos ayudarán, así que aquí está.

  • tomás zerolo dice:

    Hay tantos hermosos proveedores de correo electrónico con una configuración SMTP funcional. ¿Por qué Gmail? ¿Por qué extender el poder de The Monster?

    Ya son demasiado grandes para los suyos (¡y los nuestros!) Bien.

  • nilad dice:

    gmail de nuestro servidor de Internet favorito. usar un mensaje de protones

  • mía dice:

    O simplemente use sendgrid o mailgun para enviar el correo a través de json a través de https.

  • José Baars dice:

    Usar OAuth es difícil en comparación con poner en marcha un lavavajillas. Es tan difícil como conducir un coche de forma segura. Teniendo en cuenta la cantidad de automóviles que sobreviven al viaje diario, es factible.

Óscar Soto
Óscar Soto

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *