mail - ¿Debería un servicio de API enviar el correo electrónico de activación del usuario o la aplicación cliente?
api para envio de correo (8)
Así que la forma en que logré esto en mi opinión es bastante agradable. Así que tomé la metodología de cómo funcionan los tokens web de JSON y la apliqué a mis enlaces de activación. Te explico cómo funciona:
Tengo 2 servidores web, uno que maneja la API REST y uno que maneja el spa.
Entonces el usuario se registra, y la solicitud se envía a la API. Luego, la respuesta se devuelve al SPA, momento en el que, si se realiza correctamente, envía una solicitud al Backend del SPA que firma un token con las credenciales del usuario, el propósito del token (en este caso es verificar la dirección de correo electrónico) y su fecha de caducidad .
Este token se envía a la dirección de correo electrónico del usuario, sin embargo, en el servidor REST hay una ruta de recepción que decodificará el token y, si es válida, verifica la dirección de correo electrónico.
Esto significa que, técnicamente, solo los clientes de primera persona pueden autenticar la dirección de correo electrónico, ya que son los únicos que pueden conocer su secreto de cifrado. Si su secreto fue entregado libremente, entonces el problema sería que cualquiera podría verificar su dirección de correo electrónico.
¡Espero que esto ayude!
EDITAR: otra forma sería pasar una plantilla incorporada en manillares o algo que intercambie variables por valores reales. Luego, pida a la API REST que la represente y envíela por correo electrónico. (Esta es probablemente la mejor manera imo jaja)
Estoy tratando de desarrollar un servicio web REST API. Tengo una pregunta sobre cómo manejar el correo electrónico de activación del usuario. Actualmente, el servicio API maneja el envío de correo electrónico.
Aquí está el flujo que tengo en este momento:
- El usuario se registra a través de la aplicación cliente.
- Aplicación de cliente POSTs al servicio API
- El servicio API valida y agrega el usuario a la base de datos.
- El servicio API envía al Usuario un enlace de activación.
- El usuario hace clic en el enlace de activación, que lo llevará a la página de activación de la aplicación cliente
- Página de activación de la aplicación cliente de POST a servicio API
- Hecho
Aquí es donde veo actualmente el problema:
Debido a que el servicio de API actualmente está enviando el correo electrónico, la aplicación cliente no tiene control sobre la apariencia del correo electrónico. Y puede haber direcciones URL en el correo electrónico que deberían apuntar a la aplicación cliente.
Otra opción es que, en lugar de que el servicio API envíe el correo electrónico de activación, devuelva la clave de activación a la aplicación cliente. La aplicación cliente podrá enviar el correo electrónico de activación al usuario.
Dos problemas que veo con esta estrategia:
- Seguridad, ya que la clave de activación ahora está expuesta a la aplicación cliente.
- No SECO, ya que cada cliente podría ser responsable del envío de correo electrónico.
¿Cuál crees que es la mejor manera de manejar esto?
Me gustaría permitir que la aplicación cliente personalice su correo electrónico, así como incluir direcciones URL específicas del cliente (página de activación).
Creo que la forma correcta es exponer la clave de activación para que el cliente haga lo que quiera con.
También puede agregar otro punto final para enviar la clave de activación para el usuario.
Devuelve usuario. (con la url como User/{userid}
y otros recursos como url User/{userid}/ActivationKey)
User (POST)
Esto puede devolver al usuario actual y otros recursos como correo electrónico, activar, etc. Para obtener información sobre la clave (como fechas, vencimiento, etc.)
User/{userid}/ActivationKey
Desde allí puedes extenderlo tanto como quieras con:
Vista previa del correo electrónico de activación:
User/{userid}/ActivationKey/Email (GET)
Actualice el correo electrónico de activación con la plantilla, el servidor smtp, etc. del correo electrónico. :
User/{userid}/ActivationKey/Email (PUT)
Cree (y envíe) un correo electrónico de activación, con fecha para enviar u otras opciones de envío (versiones de texto-html, etc.):
User/{userid}/ActivationKey/Email (POST)
Posiblemente podría enumerar todos los correos electrónicos enviados y obtener una vista previa de ellos en otro punto final si es necesario.
User/{userid}/Emails (GET)
User/{userid}/Emails/{emailid} (GET)
Extendí el paso 2 con datos adicionales enviados al servidor:
"mail":{
"placeholder":"someStringChoosenByClientWhichWillBeReplaceByActivationCode",
"subject":"Hey there, please activate",
"ishtml":false,
"body":"SSdtIHRyeWluZyB0byBkZXZlbG9wIGEgUkVTVCBBUEkgd2ViIHNlcnZpY2UuIEkgaGF2ZSBhIHF1ZXN0aW9uIGFib3V0IGhvdyB0byBoYW5kbGUgdXNlciBhY3RpdmF0aW9uIGVtYWlsLiBDdXJyZW50bHksIHRoZSBBUEkgc2VydmljZSBoYW5kbGVzIGVtYWlsIHNlbmRpbmcu"
"attachments":[
{
"content-type":"image/png",
"filename":"inline_logo.png",
"content":"base64_data_of_image"
}
]
}
Esto le permitiría al cliente tener un control total sobre el mensaje enviado, pero el proceso todavía maneja el procedimiento de activación (generación y entrega de correo).
Todo el mundo, excepto la clave de activación, puede ser generado para cada usuario por el cliente (por ejemplo, utilizando "Hello XYZ" como Asunto).
No estoy seguro de si es una buena idea permitir html-Mails ( "ishtml":false,
), esto depende de su aplicación y de la cantidad de tiempo que quiera dedicar a esto.
Me a con la idea de permitir que el cliente le envíe una plantilla de su correo electrónico. (Y +1 por hablar de una manera de probar, porque estoy de acuerdo con la terrible situación del "desarrollo" del correo).
Pero ¿por qué tan complicado? Las aplicaciones cliente son desarrolladores, así que, ¿por qué no les permite que les den su plantilla predeterminada (con HTML), que jueguen si lo desean y que le devuelvan la versión que prefieren?
No es mucho trabajo para usted (solo un nuevo campo en la tabla de clientes y una nueva ruta), y les da muchas opciones.
Este es un ejemplo básico donde expondremos algunos parámetros para que puedan jugar con el HTML sin siquiera tener que conocerlos:
-
app.name
-
app.description
-
activation_code
-
user.*
registro de información
Plantilla basica
{
title: "Your activation code for %{app.name}",
body: "<p>Hi, you''ve been registered on %{app.name}.
<p>%{app.description}</p>
<p>Follow <a href="%{activation_code}">this link to confirm your inscription</a>."
}
Registrar nueva plantilla
Luego el cliente dice: "Prefiero tener un correo más simple, ¡pero quiero su nombre!".
[PUT] /api/email/templates/client_id
{
title: "Your activation code",
body: "<p>Hi %{user.fullname}, Follow <a href="%{activation_code}">this link to confirm your inscription</a>."
}
Y aquí tienes. Dejalos jugar con HTML, permite mucho mas personalizacion.
No hay nada de malo en ello, excepto su imagen en sus clientes si se equivocan, pero son sus clientes.
Temas de seguridad
Se señaló que los atacantes podrían obtener acceso al token de la aplicación cliente y podría inyectar contenido malicioso en la plantilla. En primer lugar, el riesgo ya es tan alto si la ficha se filtra, que esta es la última de sus preocupaciones. Sin embargo, si le teme esto, deshabilitar las etiquetas img
y hacer que el contenido de a
etiqueta coincida con el atributo href
debería resolver su problema.
Permitir que el cliente administre sus propias plantillas de correo electrónico. Cuando publiquen un nuevo registro de usuario, permítales especificar qué plantilla usar. Entonces su aplicación está enviando el mensaje de correo electrónico, pero los clientes pueden controlar cómo se ve.
POST /email-templates
{
"subject": "Complete Your Registration",
"body": "<html>Follow this link to complete your registration: {activationLink}. It is valid for 45 minutes.</html>"
}
POST /registration-requests
{
"name": "John Q. Public",
"emailTemplate": "/email-templates/45"
}
Su API podría tener un objeto IEmailBodyFormatter que se pasa como un parámetro a su llamada a la API ...
TL; DR
Cree un pequeño servicio para que los desarrolladores creen plantillas, permítales declarar qué plantilla desean usar cuando POSTEN a su API de activación
Resumen del problema:
- El correo electrónico debe verse diferente para cada aplicación cliente
- el envío de correo debe ser implementado una vez
- la solución debe ser segura
No es necesario que el correo electrónico se vea diferente cada vez. Por lo tanto, no es necesario enviar el formato de correo electrónico con la solicitud POST.
En su lugar, se puede hacer uno de los siguientes:
1 Cree un punto final de API separado para definir las plantillas y deje que la aplicación cliente elija una de ellas al POSTAR la solicitud de activación.
Esto no es exactamente seguro, al menos plantea un desafío para hacerlo seguro si desea aceptar HTML de las aplicaciones cliente.
Solución recomendada:
2 Cree una herramienta para desarrolladores (en el mismo sitio web donde obtienen su clave de API) que acepte plantillas y ayude a crearlas. La aplicación del cliente puede elegir una de ellas al POSTAR la solicitud de activación. Fragmento del cuerpo de la solicitud siendo algo así como:
...
"template": "foobar-app",
"fields": {
"title": "Welcome to foobar app",
"username": "jim78"
}
...
No se permite HTML en los campos.
Esto le permite tener plantillas predefinidas preparadas por el desarrollador que pueden ser utilizadas por su servicio de envío de correo electrónico y ningún error en la aplicación cliente puede hacer que el correo electrónico se vuelva inseguro. Además, obtienes un lugar donde se pueden trabajar y probar las plantillas. (El desarrollador puede enviarse a sí mismo para depurar, hacer plantillas de correo electrónico es horrible, créeme)
Podrá apoyar mejor a sus desarrolladores / clientes en el futuro y preparar un conjunto de plantillas de trabajo probadas en varios clientes de correo.
Un punto sobre seguridad y confianza. Normalmente, usted envía un correo electrónico de activación que contiene un enlace url que tiene el código de activación. El propósito del correo electrónico es validar que el correo electrónico es válido y que el usuario tiene acceso a ese correo electrónico. La única forma en que el usuario pudo haber recibido el enlace de verificación es a través del correo electrónico.
Si devuelve el enlace de activación al cliente, cualquier persona que tenga acceso a su API tendrá acceso al código de activación. Si tienen acceso al enlace, pueden pasar por alto el proceso de verificación. Esto es realmente sencillo si tiene una aplicación web, ya que solo tienen que pasar al modo de desarrollador del navegador para ver el enlace. Si tiene un cliente gordo, entonces podrían rastrear la red si no está utilizando el cifrado como https. También podrían, si fueran dedicados, descompilar su binario (esta es la razón por la que no almacenaría claves en sus binarios).
Un backend nunca debe confiar en que un cliente implemente un procedimiento de seguridad porque nunca sabe cuándo se ha comprometido. La forma segura y correcta es hacer el correo electrónico de activación en el lado del servidor. Otra forma de ver esto, es que es similar al cliente que dice "sí, el usuario está autenticado, así que dame todos los datos"
En cuanto a las plantillas hay muchas buenas respuestas arriba. Yo sugeriría tener un catálogo de plantillas y una lista de argumentos que puedan ser reemplazados.