Pull to refresh

Сохраняем состояние страницы после авторизации VK с помощью Broadcast Channel API

Reading time3 min
Views2.6K

Недавно в работе с одним из наших клиентов мы столкнулись с проблемой в пользовательском сценарии: VK API требует конкретный, железный URL для редиректа после авторизации. А у нас были сотни ссылок с динамическими параметрами, с которым могла начаться авторизация. 

Меня зовут Фёдор Макареев, я frontend-разработчик в Evrone. В статье расскажу, как я применил Broadcast Channel API, чтобы не терять состояние до авторизации и не бесить пользователей.

Пользователи полюбили SSO-авторизацию: не надо помнить десятки логинов-паролей, а сам процесс регистрации и входа в сервис теперь выглядит почти бесшовным. Сервис, в который нельзя зайти через аккаунт соцсетей или почты, сегодня выглядит несовременным, так что можно говорить о своего рода стандарте пользовательского сценария.

В нашем случае речь шла об авторизации через VK (с помощью authcode-flow-user), хотя описываемый метод применим, например, к Одноклассникам или другим соцсетям. 

Как это должно работать

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

Мы заранее формируем ссылку для перехода в VK примерно такого вида:

https://oauth.vk.com/authorize?client_id=1&display=page&redirect_uri=http://example.com/callback&scope=friends&response_type=code&v=5.131

С нашего сайта клиент переходит по ссылке, предоставляет права на авторизацию с помощью своего VK аккаунта. VK объясняет пользователю, какие данные будут расшарены, получает подтверждение и перенаправляет на адрес, который мы указали в первом шаге redirect_uri=http://example.com/, предоставив нам code.

Этот код отправляется на бэкенд для получения информации о пользователе.

Проблема — форма авторизации может быть где угодно на сайте

Виджет авторизации/регистрации не привязан к конкретному адресу и может быть вызван с множества адресов. VK требует указать в настройках приложения все возможные redirect_uri. При этом, VK проверяет их на строгое сравнение и не даёт использовать динамические адреса.

Можно установить единую страницу для redirect_uri, на которой пользователь продолжит регистрацию. Тогда пользователь потеряет состояние страницы, с которой он ушел для регистрации/авторизации, и ему придется всё делать по новой. 

Решение — слушаем процесс авторизации и сохраняем состояние пользователя

Я начал изучать, как вообще можно узнать, что происходит в соседней вкладке или окне. Вот, например, статья, которая даёт 4 возможных варианта: Local Storage Events, Broadcast Channel API, Service Worker Post Message и Window Post Message.

Local storage event использует промежуточное хранение данных в кэше, которым придется управлять вручную, это не так удобно. Service Worker Post Message — тоже не очень подходит для этой задачи, так как не дает явно настроить тип сообщения, которое я отправляю. Пришлось бы вручную добавлять в объект с данными поле type, а в месте, где я подписан на него, добавлять проверку значения этого поля. Window Post Message не подошёл по этой же причине.

Я использовал Broadcast Channel API для обмена сообщениями и полифил для него broadcast-channel. Вот как это работает:

  1. В настройках приложения на стороне VK указываем один единственный redirect_uri.

  2. Клиент начинает авторизацию, перенаправляется на сайт VK в новом окне, это окно вызывается с помощью window.open. На странице, которая инициирует создание окна, создается канал обмена сообщениями:
    const bc = new BroadcastChannel('vk_auth_channel');
    И устанавливается прослушка этого канала на получение сообщений:
    bc.onmessage = event => { console.log(event.data); }

  3. На странице, куда VK перенаправит пользователя (страница из redirect_uri), будет скрипт. Он создаст такой же канал, но уже для отправки сообщений. Из параметров достаем код или ошибку, отправляем по каналу vk_auth_channel статус, code:
    bc.postMessage({status: true, code});
    Или ошибку:
    bc.postMessage({status: false, errors});

  4. После чего закрываем окно. Полученный code можно отправлять на бэкенд для обработки.

Посмотреть на полный процесс авторизации через VK вместе с бэкендом можно в этой хорошей статье. Вместе с описанным выше подходом вы получите авторизацию через ВК без привязки к странице. Это полезно, чтобы не прерывать пользовательский сценарий и случайно не устроить взрывной отток юзеров.

Tags:
Hubs:
Total votes 19: ↑19 and ↓0+19
Comments6

Articles

Information

Website
singula.team
Registered
Founded
2008
Employees
31–50 employees
Location
США