As IS
Текущий апи использует GraphQL и состоит из трех основных методов связанных с регистрацией:
Register:
mutation PlayerRegisterUniversal(
$bmsPartnerId: Int!
$input: PlayerRegisterUniversalInput!
$locale: Locale!
$deviceFingerPrint: String
) {
playerRegisterUniversal(
bmsPartnerId: $bmsPartnerId
input: $input
locale: $locale
deviceFingerPrint: $deviceFingerPrint
) {
problems {
message
problemCode
traceId
__typename
}
record {
sessionToken
userName
id
email
__typename
}
status
__typename
}
}
Где input:
{
"input": {
"email": "[email protected]",
"password": "34567821343",
"mobileNumber": "555",
"currency": "AZN",
"affiliateData": "https://alovcasino127.com/?stag=66885_67b7297f4766b0bba2728080&popup=signup"
},
"bmsPartnerId": 2,
"locale": "en",
"deviceFingerPrint": "1f19915a762c274d6375e719edafc009"
}
login:
mutation PlayerLogin(
$bmsPartnerId: Int!
$input: PlayerLoginInput!
$locale: Locale!
$reCaptchaToken: String
$isMobile: Boolean
$deviceFingerPrint: String
) {
playerLogin(
bmsPartnerId: $bmsPartnerId
input: $input
locale: $locale
reCaptchaToken: $reCaptchaToken
isMobile: $isMobile
deviceFingerPrint: $deviceFingerPrint
) {
problems {
message
problemCode
traceId
__typename
}
record {
email
sessionToken
userName
__typename
}
status
__typename
}
}
В примере выше affiliateData содержит данные из localStrorage браузера.
recoveryPassword
mutation PasswordSendRecoveryTokenByEmailMutation(
$bmsPartnerId: Int!
$locale: Locale!
$input: PasswordSendRecoveryTokenByEmailInput!
) {
passwordSendRecoveryTokenByEmail(
bmsPartnerId: $bmsPartnerId
input: $input
locale: $locale
) {
recordId
status
problems {
message
problemCode
traceId
__typename
}
__typename
}
}
Сценарии, которые не покрываются
Поэтапная валидация
Сейчас мы отправляем форму целиком, после заполнения всех полей. Но для улучшения ux оптимально было бы вызывать методы валидации еще на этапе заполнения поля, на onBlur событие, или с каким то debounce по мере ввода.
К примеру для емейла мы можем совершать проверку в mailcheck.co или аналоге, на этапе заполнения емейла. Так же можем проверять что такой емейл уже занят, проверять что емейл не содержит опечаток и т.п.
Либо можем осуществлять подстановку исправленного домена.
К примеру для поля пароль мы можем проверять соответствие условиям еще на клиенте, но какой-нибудь haveIbeenpwned мы должны проверять на бекенде.
К примеру для поля телефон мы можем сразу проверять корректность длины номера касательно гео кода и т.п.
Самое важное для нас поле это промокод, нам желательно его валидацию делать до попытки зарегистрироваться (показывать есть ли такой промокод, и опционально еще и условия бонуса).
Для реализации поэтапной валидации предлагается добавить новые мутации (verifyEmail, verifyPassword, verifyPromo), и вызывать их с фронтенда, на этапе валидации формы.
Прослеживание событий
В рамках документа по аналитике, мы запросили лог всех запросов на регистрацию\валидацию которые приходят на бекенд. Однако для возможности построения воронки нам необходимо дополнительно иметь возможность связать данные одного пользователя в цепочку. Для этого можно использовать параметр fingerprint который уже есть, но я бы предложил ввести отдельный cookies который бы содержал timestamp первого визита человека на сайт + энтропия. С точки зрения анализа мы таким образом легко можем проследить попытки регистрации человека на продукте, и сразу наглядно видим время от попадания на сайт до регистрации.
Social Auth \ Google One Tap
При использовании авторизации через соц сети возникает ряд вопросов - как к примеру передавать данные партнерской регистрации? Спецификация oauth поддерживает дополнительный параметр - state, который можно использовать для проброса параметров сквозь флоу авторизации на стороне провайдера решения. Таким образом на SoftGaming к примеру реализован проброс параметров партнерки через социальную регистрацию. Возможно вы выберете другой подход, но хочу отметить что к данным SSO авторизации можно прикладывать кастомный payload, используя state параметр.
Рекомендации
Партнерские данные
На данный момент партнерские данные сохраняются в localStorage, однако не обнаружен момент истечения партнерских данных. В целом в индустрии принято сохранять данные об атрибуции в куках — так и партнерам привычнее, и есть автоматический expiry. В случае полностью статичного фронтенда для этого можно воспользоваться к примеру добавочной мутацией - setPartnerData, которая бы уже возвращала cookies. Я вижу что сейчас сохраняются полные данные (в виде всего url), это очень удобно, потому что мы сохраняем, в том числе и utm и иные аттрибуты, хорошо так же сохранять их в cookie.
Кросс доменная авторизация
У нас есть необходимость использовать зеркала, что приводит к тому, что людей разлогинивает периодически на продукте. Этот вопрос можно решить, используя 3й домен, как хранилище авторизационных данных. К примеру alovsecret.com/api/session, домен на котором нет продукта реализует http метод, который принимает в себя RestoreSessionToken, и устанавливает его в cookies. Тогда при заходе на другое зеркало продукта, фронтенд может делать запрос на alovsecret, и извлекать Token для восстановления авторизации. Возможность извлечь cookies определяется настройками CORS, что означает что мы не позволим посторонним узнать наш restore token. Но при этом авторизационная сессия игрока будет активной на всех зеркалах. Важно: мы хотели бы видеть информацию о всех восстановленных сессиях в аналитике. Поэтому я бы предложил ввести дополнительную мутацию - restoreSession, в которую передавать информацию о restoreToken, чтобы вести учет как успешных восстановлений, так и ошибок восстановления.
TurnStile
Я не смог словить recaptcha, но судя по контракту ее поддержка на форме есть. Я бы предложил использовать turnstile в скрытом режиме, вместо recapthca. В этом режиме он будет проводить аттестацию браузера в фоне, и показывать валидацию только разным подозрительным пользователям, живые игроки его вообще не увидят. Учитывая достаточно высокие рейт лимиты на продукте, я очень рекомендую хотя бы такой механизм защиты использовать.
Скрывать количество пользователей на продукте
Сейчас после успешной регистрации я получаю в ответе поле "id". Сделав 10-15 регистраций легко убедится что это монотонно возрастающий параметр, указывающий на номер регистрации в базе данных. Таким образом я знаю что сейчас на alov 68062 регистрация (из которых примерно 100 мои). Я бы рекомендовал заменить такой ид на nanoid или аналог, но не показывать пользователям количество регистраций на продукте.
безопасная реализация авторизации
на данным момент при регистрации или логине я получаю параметр sessionToken. Это не https secure cookie, это просто поле в API responce, которое далее используется для запросов к бекенду. Я бы рекомендовал следовать bestPractice по безопасности и использовать либо secureCookies для сессий, либо если нет возможности — перейти на jwt с refresh токеном. Я предполагаю что сейчас это не проблема, но я бы рекомендовал по возможности реализовать механизм авторизации безопасно, до того как у нас будут тысячи активных сессий.