Magic link или история о том, как мы упростили жизнь пользователю

в 12:56, , рубрики: hash, magic link, php, UI, авторизация по хэшу, Анализ и проектирование систем, волшебная ссылка, интерфейсы, Проектирование и рефакторинг, Развитие стартапа, хэш-авторизация

В статье я поделюсь личным опытом разработки и реализации “волшебных ссылок”. Расскажу зачем они нужны в нашем проекте, как функционируют и в конце даже всплакну над тем, что отсутствие такого функционала в больших системах используемых мною заставляет меня гневно рвать на себе волосы.

Код будет только в одном месте, т.к. основная цель статьи — рассказать про саму идею, а не показать то, насколько красив код.

Magic link или история о том, как мы упростили жизнь пользователю - 1

Вступительное бла бла бла

Порой прочитать и изучить чужой опыт гораздо проще, чем часами ломать голову себе и своим соклавишникам в реализации нового “уникального” функционала. Уникальное в наше время редко где встретишь. Зачастую любой функционал уже кем-либо использовался и тебе, кнопкодав, остаётся только интегрировать его в свою рабочую область.

В проекте, над которым я работаю, любой пользователь может зайти задать вопрос юристам. Это его основная задача, которую в статье я и буду рассматривать.

Какой у меня пароль?

Приходя на нашу платформу, пользователю надо только одно — помощь. Он не хочет регистрироваться, а затем авторизовываться только для того, чтобы задать вопрос. Ему нужен ответ здесь и сейчас.

Изначально у нас нельзя было задать вопрос не будучи залогиненным. Пользователи к этому никаких претензий не предъявляли. В форме регистрации ввести ящик и пароль не оказалось проблемой. Изначально юристы реагировали медленно, т.к. вопросов было не много, а потому клиент даже успевал забыть, что такой вопрос у него есть. Получив ответ в системе и уведомление на свою почту, пришло время клиенту узнать что же там юрист такого написал. И тут наступает коллапс: бОльшая часть пользователей не осилила авторизацию, т.к. банально забыли пароль. И не то, чтобы у нас не было формы восстановления пароля, но она не сильно помогала. Мы стали терять клиентов…

Хочу просто задать вопрос

Приняли решение, что можем открыть возможность создания вопроса для гостей. Клиент в форме создания сущности дополнительно вводит почтовый ящик и всё. Нет шага регистрации. Клиент захотел задать вопрос — он его задал.

Юрист, взяв в работу заданный гостем вопрос, даёт раскрытый обширный ответ с учётом всех кейсов… кхм… пишет пару строчек умных слов и всё — ответ дан.

нашпроект.ком алахомора!

Система отправляет клиенту уведомление о том, что на его вопрос был дан ответ. Но в письме появляется некая ссылка — magic link, при клике на которую происходит авторизация пользователя и он с довольным лицом оказывается на странице своего вопроса. Всё.

Тут и сказочке конец, а кто слушал молодец.

Теперь я расскажу о технической стороне этого “прогресса”.

Запили мне хэш

Проект состоит из 2х частей: фронт и бэк. На бэке был разработан сервис, который отвечает за работу системы magic link.

Изначально система генерирует рандомный набор из 6 символов (буквы + цифры) — hash, который сохраняет в базу. На уникальность hash, конечно же, проверяется.

У каждого хэша есть своё время жизни, которое зависит от роли пользователя, для которого он генерируется (т.к. позже такие ссылки стали приходить и юристам, у которых память на пароли ещё дырявее) и типа операции, в результате которого он был сгенерирован (ответ на вопрос, создание вопроса, комментарий и т.п.). Пользователей у нас в базе порядка 14 000, т.е. мало и 6-символьный хэш, как показывает практика, пока себя вполне адекватно ведёт. Хэши, у которых истёк срок действия удаляются. Мы решили, что 6 символов — идеальный вариант для запоминания или самостоятельного ввода в адресную строку, которая, к слову выглядит весьма красиво — /hash/haSH12.

Каждый хэш привязан к тому пользователю для которого он генерируется. Также он привязан к сущности (ID + тип), операция над которой вызвала генерацию хэша.

Переходя по magic link фронт отправляет на бэк хэш и ждёт в ответе указания что делать дальше. Если хэш валиден — происходит авторизация пользователя и последующий его редирект на детальный просмотр сущности. Если хэш не валиден — фронт просит пользователя авторизоваться.

Со временем развития платформы прилетело требование о том, что в случае операции комментирования пользователь, переходя по хэшу, должен скроллиться к новому комментарию. Таким образом, хэш получил дополнительную настройку, которую мы назвали “локация” и в которой храним роут фронта с дополнительными параметрами (в данном случае ID комментария), на который происходит редирект пользователя после авторизации.

Следующее развитие платформы потребовало возможность выполнения ряда операций перед тем, как пользователь будет авторизован. Например, верифицировать профиль или запустить какой-то таймер дедлайна ответа на вопрос. Это подарило хэшу настройку с названием “алиас”. Система обработки хэшей, находя нужный хэш в базе, смотрит на наличие алиаса — обычная строка, которая хранит текстовую константу. Если алиас есть, по нему система создаёт вызов метода, в котором и выполняются необходимые операции до того, как пользователь будет авторизован

public function executeAlias()
{
    if(!$this->hash->alias){
	return $this;
    }

    //camelCase alias
    $aliasMethod = Str::camel($this->hash->alias);

    if(!method_exists($this, $aliasMethod)){
	return $this;
    }

    return $this->{$aliasMethod}();
}

Данная система по управлению хэшами настолько хорошо себя зарекомендовала, что мы её распространили на доступ к файлам. Ситуация простая: в вопросе клиент загружает файл, бэк сохраняет его у себя где-то там в тёмных недрах сервера, но пользователи (что клиент, что юрист) видят красивую ссылку /storage/hash12/some_CODE. Система по управлению файловыми хэшами при загрузке файла сразу генерирует пару хэш-код и к ним дополнительно привязывает путь к файлу и всё это сохраняет в базе.

Код мы планируем интегрировать и для magic link, чтобы в будущем использовать его для двухфакторной авторизации. Пользователь, переходя по magic link будет получать на телефон код и вводить его в предложенной фронтом форме.

Данная система позволила нам настроить удобный и гибкий доступ пользователя к системе. Анализируя ситуацию, мы понимаем, что ошибки с неправильным вводом пароля и количество писем с напоминанием пароля почти сошли на “нет”. Мы можем изменять время жизни каждого хэша отдельно или генерировать его для какого-то отдельно взятого пользователя по его запросу.

Плак, плак

И в конце всплакиваю. Всплакиваю от того, что сайтыплатформы, которыми иногда пользуюсь такую систему не используют или в качестве хэша выступает строка из 40 символов, т.к. иногда есть необходимость не переходить по ссылке из письма, а ввести её вручную в адресной строке. Хотя, не отрицаю того, что с ростом нашего проекта когда-то и мы придём к длине такого хэша…

Спасибо за внимание.

P.S. напоминаю, что это личный опыт и я оставляю свой камушек в большом огороде информации.

Автор: alutskevich

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js