В Яндекс.Почте совсем недавно появилась новая возможность — письма в смс. Мы сделали её не только для тех, кто любит бесплатно отправлять текстовые сообщения, но и для тех, кому нужна быстрая реакция получателя. Теперь из веб-интерфейса почты вместе с письмом вы можете оправлять смс-сообщение со ссылкой на копию самого письма.
Ссылка откроется в специальном мобильном интерфейсе, не требующем авторизации. Там же можно прочитать письмо и ответить на него. При этом совершенно не важно, на каком сервисе находится электронная почта получателя. Сегодня мы раскроем несколько секретов о технических деталях реализации.
Уведомить получателя об отправленном письме можно было и раньше, но с небольшими ограничениями. Например, если письмо было отправлено не на Яндекс.Почту, смс выглядело вот так:
Это было обычное уведомление без возможности прочитать письмо и ответить на него. К тому же, уведомление отправлялось только после доставки письма адресату. Мы сделали это специально для того, чтобы исключить возможность доставки смски до того, как стороний сервер примет письмо. Реализовали путём добавления зашифрованных служебных заголовков к письму и проверки этих заголовков в DSN-баунсе, полученном от принимающей стороны. В новой версии мы всё перекроили.
Во-первых, дали доступ к отправленному письму. Новая версия подразумевает не просто уведомление о доставке. Теперь можно сообщать пользователю, что ему было отправлено письмо вне зависимости от того, доставлено ли оно в его почтовый ящик.
Это позволяет дать доступ к письму, даже если другой почтовый сервис по какой-то причине письмо потеряет, либо если адресат был введён неправильно. Само письмо, открытое из смс, выглядит так:
А во-вторых, благодаря тому, что в новой версии из цепочки отправитель-получатель исчезла необходимость получения письма другим сервером, мы позволили себе посылать смс сразу после отправки письма.
Безопасность
Вопросу безопасности мы уделили очень много времени и внимания, потому что его можно назвать самым сложным в этой задаче. Многие аспекты архитектуры изначально прорабатывались, исходя именно из соображений защищённости данных пользователя от любых посягательств и мошенничества:
- Когда пользователь отправляет письмо с смс-уведомлением, оно сохраняется как отправленное. По уникальным данным формируется ключ, зашифрованный с помощью AES и обёрнутый для удобства в Base64. Все операции с письмом происходят по этому ключу.
- При попытке открыть письмо по ссылке из смс-сообщения проверяется время его создания. Письмо доступно только в течение двух часов после отправки. Как нам кажется, двух часов вполне достаточно, чтобы прочитать смс и ответить на него. А поскольку возможность ответа на письмо со страницы просмотра без аутентификации потенциально небезопасна, мы ограничили количество ответов с неё.
- В целях предотвращения отправки спама мы решили не передавать различную метаинформацию (ареса, телефоны и т. п.) с клиента http-аргументами. Таким образом, их нельзя подменить и отправить письмо на произвольный адрес.
Для этих целей развёрнута отдельная база данных — MongoDB. Она проста, легковесна, хорошо масштабируется и пригодится нам в дальнейшем для самых разных задач. Опыт знакомства с MongoDB оказался интересен и полезен — свобода управления коллекциями и структурой записей позволяет программистам меньше зависеть от администраторов баз данных. Это ускоряет проектирование, прототипирование, разработку и дает возможность экспериментировать с форматами и операциями.
Производительность этой базы также позволяет легко использовать её и для более «тяжёлых» задач. Нагрузочное тестирование показало, что при смешанных запросах и небольших объёмах данных (100b, 3kb) связка «веб-сервер -> backend -> mongoS -> DB» выдерживает минимум 6000 запросов в секунду, а время ответа укладывается в 40 миллисекунд. Используется многопоточный бекенд, реализующий бизнес-логику, и пул коннектов к БД. Во время тестирования база состояла из одной машины с SATA-дисками. Сейчас её конфигурация состоит из трёх шардов, в каждом — репликасет из трёх машин на SSD-дисках. Для использования пула коннектов над всеми MongoS поднят tcp-балансер, потому что C++ драйвер не умеет подключаться к нескольким машинам с failover'ом.
Кроме того, мы приняли много других мер по обеспечению безопасности писем пользователя от несанкционированного просмотра и использования. В самых разных частях системы генерируются и сверяются всяческие хеши, дайджесты, проверяются хосты, таймстампы. Сокращатель ссылок был специально перенастроен так, чтобы идентификационный хеш был длиннее и имел равномерное распределение, что делает бесполезным перебор ссылок.
О будущем
Как и любую новую возможность, письма в смс мы запускаем достаточно осторожно: нужно быть уверенным в том, что сервис не только отработает корректно, но и выдержит нагрузку. Именно поэтому в первое время мы не выносим настройку отправки смс на видное место, оставив её за галочкой «Отправить адресату SMS-уведомление после отправки письма» в самом низу страницы написания письма.
Как нам кажется, сейчас полёт нормальный, поэтому в ближайшее время новая возможность будет продвигаться в интерфейсе почты. И хотя обычно мы не раскрываем своих планов, сегодня для вас сделаем исключение и покажем скришншот интерфейса отправки смс в том виде, в котором его увидят миллионы пользователей Яндекс.Почты после того, как он пройдёт все испытания:
Автор: jkennedy