Авторизация по номеру телефона

Классы и методы с примерами

В модуле имеется несколько основных классов для работы с модулем.

Класс для работы с ошибками:

\Bxmaker\AuthUserPhone\Error

Класс используемый для возвращения результата выполнения операций

\Bxmaker\AuthUserPhone\Result

Основной класс для работы с модулем:

\Bxmaker\AuthUserPhone\Manager

Класс для работы с таблицей в базе данных, в которой хранятся данные по временным кодам отправленным пользователям, отдельно по каждому сайту (используется мультисайтовость):

\Bxmaker\AuthUserPhone\ManagerTable

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

\Bxmaker\AuthUserPhone\Manager\LimitTable

Практически все что вам может понадобится уже есть в методах класса Manager(), поэтому вам не придется работать с другими классами, такими как ManagerTable, LimitTable и др.

Result

Класс \Bxmaker\AuthUserPhone\Result используется для возвращения результат выполнения того или иного действия.

$oResult = new \Bxmaker\AuthUserPhone\Result('Здесь какой то результат, например true');

В случае наличия ошибки, можно указать только текст ошибки, а можно и код ошибки, и дополнительную информацию по ошибке

$oResult = new \Bxmaker\AuthUserPhone\Result(new \Bxmaker\AuthUserPhone\Error('текст ошибки'));

Методы класса Result

  1. В экземпляре объекта можно установить значение результирующее как сразу, при инициализации, так и после используя метод setResult();
$oResult->setResult('результат, например код статуса отправки смс');
  1. Также помимо установки результат, можно отметить в любой момент что появилась ошибка, используя метод setError();
$oResult->setError(new \Bxmaker\AuthUserPhone\Error('текст', 'код', array('больше' => 'информации')));
  1. Также к результату можно добавить дополнительную информацию, используя метод setMore();
$oResult->setMore('ключ', 'значение');
  1. Для проверки наличия ошибок используется метод isSuccess();
if($oResult->isSuccess())
{
   /* ошибок нет */
}
else
{
   /* ошибки есть */
}
  1. Для получения результата используется метод getResult();

    $oResult->getResult();
    
  2. Для получения дополнительной информации - getMore();

// по умолчанию возвращается весь массив 
$oResult->getMore();

//также можно запросить только значение с нужным ключом, при 
//этом если значение не найдено, будет возвращено значение == null 
$oResult->getMore('phone');
  1. Для получения ошибок используется метод getErrors();
/* данный метод возвращает массив экземпляров объекта \Bxmaker\AuthUserPhone\Error */
$arErrors = $oResult->getErrors();
foreach($arErrors as $error)
{
   $error->getMessage();
}
  1. Также можно поучить сразу массив с сообщениями об ошибках - getErrorMessages();
    echo implode(', <br> ', $oResult->getErrorMessages());
    

Error

Класс \Bxmaker\AuthUserPhone\Error используется для стандартизации вывода ошибок, в результате в качестве ошибки возвращается экземпляр класса Error, имеющий всего 3 метода.

$oError = new \Bxmaker\AuthUserPhone\Error(
'Текст ошибки', 
'Код ошибки если есть, по умолчанию = 0',
 array('инфо' => 'массив с дополнительной информацией, которая может понадобится, например'));

Методы класса Error

  1. Для получения текста ошибки. существует метод getMessage();

    echo $oError->getMessage();
    
  2. Получение кода ошибки - getCode();

    echo $oError->getCode();
    
  3. Получение массива с дополнительной информацией getMore();

    echo '<pre>';
    print_r($oError->getMore());
    echo '</pre>';
    

Manager

Класс \Bxmaker\AuthUserPhone\Manager класс является основным при работе с модулем, для входа на сайт по номеру телефона, регистрации, отправки временных кодов, проверки их валидности, проверки лимитов, получения и проверка капчи и прочего.

\Bitrix\Main\Loader::includeModule('bxmaker.authuserphone');
 
$oManager = \Bxmaker\AuthUserPhone\Manager::getInstance();

Методы класса Manager

Проверка валидности номера телефона

Для проверки валидности номера телефона используется метод isValidPhone(). Формат ввода телефона для проверки не важен, так как перед проверкой он будет очищен от лишних символов.

if($oManager->isValidPhone('+7 (999) 11-22-33))
{
   echo 'Номер телефона введен верно';
}

Подготовка номера телефона

Для подготовки номера телефона, очищения его от лишних символов, используется метод getPreparedPhone().

$phone = '8(999)11-22_33';
$phone = $oManager->getPreparedPhone($phone);

echo $phone; /* выведет 79991112233 */

Проверка необходимости редиректа

Метод isNeedUserRedirect() используется для того чтобы проверить нужно ли пользователя переадресовывать на страницу профиля для заполнения обязательных полей профиля. Параметры устанавливаются в настройках модуля.

if($oManager->isNeedUserRedirect('8 (999)1112233'))
{
   echo 'Нужно переадресовывать';
}

Метод isNeedUserRedirectByID() делает тоже самое, только в качестве аргумента необходимо вместо номера телефона передать идентификатор пользователя.

if($oManager->isNeedUserRedirectByID('12'))
{
   echo 'Нужно переадресовывать';
}

Получение URL страницы профиля

Метод getUserProfileUrl() используется для получения URL адреса страницы профиля на сайте, указанный в настройках модуля.

LocalRedirect($oManager->getUserProfileUrl());

Проверка необходимости вывести captcha

Метод isNeedCaptcha() используется для проверки необходимости вывода капчи для авторизации на сайте пользователя, данные для определения берутся из полей профиля пользователя в базе данных.

$userId = 12;
if($oManager->isNeedCaptcha($userId))
{
   echo 'Нужно вывести каптчу';
}

Возвращает sid капчи

Метод getCaptchaCode() используется для получения кода капчи, для дальнейшего использования.

$code = $oManager->getCaptchaCode();

Возвращает путь для картинки капчи

Метод getCaptchaImageSrc() используется для получения пути до картинки с капчей.

$code = $oManager->getCaptchaCode();
$imgSrc = $oManager->getCaptchaImageSrc($code);

Возвращает массив с данными о капче

Метод getCaptchaForErrorMore() используется для получения массива с данными капчи, кода и пути к картинке.

$arCaptcha = $oManager->getCaptchaForErrorMore();

echo $arCaptcha['CAPTCHA_SID']; // код
echo $arCaptcha['CAPTCHA_SRC']; // путь к картинке

Проверка наличия данных о капче и проверка валидности

Метод getCaptchaCheck() используется для проверки наличия в запросе данных о капче, параметров - captcha_sid и captcha_word.

Если данные отсутствуют то возвращается объект Result с ошибками.

Если же данные присутствуют, то проверяется валидность данных. В случае если капча введена не верно, то возвращается соответственно объект класса Result с ошибкой.

$res = $oManager->GetCapthcaCheck();
if($res->isSuccess())
{
   var_dump($res->getResult()); // true
  // данные о капче присутствуют и данные верны
}
else
{
   /* в ошибке будет возвращено сообщения что данные по капче отстствуют 
или, если пристуствуют, то сообщение что символы введены не верно */

   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
   }
}

Проверка капчи

Метод isValidCaptchaCode() используется для проверки введенной капчи, возвращается либо true, либо false;

// если аргументы отсутствуют или равны null, то берутся значения из 
// $_REQUEST['captcha_sid'] и $_REQUEST['captcha_word'] соответственно
if($oManager->IsValidCaptchaCode($captchaCode = null, $captchaWord = null))
{
   echo 'символы с картинки введены ВЕРНО';
}
else
{
   echo 'не верно введены символы с картинки';
}

Проверка лимита попыток входа

Метод isOverLimitAttempts() проверяет не достигнут ли лимит на количество попыток ввода номера телефона и пароля, временного кода.

if($oManager->isOverLimitAttempts('7999 111-22-33', $siteId = null))
{
   echo 'Достигнут лимит, необходимо с ошибкой вернуть данные для капчи, используя например метод  getCaptchaForErrorMore(), чтобы вывести на стороне клиента';
}

Фиксирование попытки входа

Метод increaseAttempts() используется для фиксирование попытки входа на сайт с использованием номера телефона и пароля, временного кода из смс. Затем данные которые фиксируются этим методом, используются методом isOverLimitAttempts();

$oManager->increaseAttempts('7 999 111-22-33', $siteId = null);

Сброс счетчика попыток входа

Метод removeAttempts() используется после авторизации пользователя для сброса счетчика попыток входа с использованием номера телефона и пароля, временного кода.

$oManager->removeAttempts('7 999 111-22-33', $siteId = null);

Получение временного кода

Метод generateCode() возвращает временный код, для последующей отправки в смс исходя из настроек модуля.

$code = $oManager->generateCode();

Отправка временного кода

Метод sendCode() используется для отправки кода в смс, при этом временный код будет автоматически сгенерирован и будет вызвано событие, сигнализирующее что необходимо отправить смс. В методе вызывается событие onSendCode. В режиме отладки интервал до возможности повторной отправки отсутствует.

$res = $oManager->sendCode('7 999 111-22-33');
if($res->isSuccess())
{
  echo $res->getMore('MSG'); //сообщение что успешно отправлено
  echo $res->getMore('TIME'); // количество секунд до возможности отправить смс повторно
}
else
{
  // если номер телефона введен с ошибками
  // если не истекло время таймаута до возможности отправить код повторно

   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
   }
}

Проверка временного кода

Метод isValidCode() используется для проверки временного кода, проверка осуществляется как по правильности введенных символов так и на время действия кода. Время действия кода задается в настройках модуля.

if($oManager->isValidCode('7 999 111 -22-33', '0000'))
{
   echo 'код введен верно';
}

Таймаут до повторной отправки СМС кода

Метод getTimeout() возвращает количество секунд оставшееся до возможности повторной отправки временного кода (временный код каждый раз генерируется новый) в секундах.

$time = $oManager->getTimeout('7999 11-22-33');

Таймаут до повторного звонка от бота

Метод getTimeout() возвращает количество секунд оставшееся до возможности повторного запроса звонка от бота в секундах.

$time = $oManager->getTimeout($phone, null, \Bxmaker\AuthUserPhone\Service::ACTION_BOTCALL);

Установка номера телефона пользователя

Метод setPhone() используется для установки номера телефона пользователю. В результате возвращается объект класса Result.

$res = $oManager->setPhone($userId = '12', $phone = '7 999111-2244');
if($res->isSuccess())
{
    echo $res->getMore('MSG');
   echo $res->getMore('PHONE'); // 79991112244
   echo $res->getMore('PHONE_RAW'); // не очищенный номер 7 999111-2244
   echo $res->getMore('USER_ID');
}
else
{
   // проверка валидности номера телефона, формат не важен
   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
   }
}

Возвращение номера телефона пользователя

Метод getPhone() используется для получения номера телефона конкретного пользователя, в результате возвращается номер телефона или null.

$phone = $oManager->getPhone($userId = '12');
if(is_null($phone))
{
   echo 'Номер телефона не установлен';
}
esle
{
   echo $phone;
}

Возвращает идентификатор пользователя по номеру телефона

Метод getUserIdByPhone($phone, $bActiveOnly = true) используется для поиска пользователя по номеру телефона, в результате возвращается объект класс Result.

$res = $oManager->getUserIdByPhone('7 999 111 22 33');
if($res->isSuccess())
{
 $userId = $res->getResult();
}
else
{
   // ошибка валидности номера телефона
  // ошибка пользователь не найден
   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
   }
}

Установка пароля пользователя

Метод setPassword() используется для установки нового пароля пользователю, в результате возвращается объект класса Result. А также в в этом методе вызывается событие onUserChangePassword.

// если пароль не задан, то он будет сгенерирован исходя из настроек модуля

$res = $oManager->setPassword($userId = 12, $password = null);
if($res->isSuccess())
{
   echo $res->getMore('MSG'); // пароль успешно установлен

}
else
{
   // ошибка длины пароля, минимум 6 символов 
   // другая ошибка  в результате которой не удалось установить новый праолль
   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
   }
}

Проверка кодов, звонков checkConfirm()

В некоторых методах используется логика проверок. Сама проверка выглядит с использованием метода checkConfirm() так:

$phone = '7(999)111-22-33';
$confirmType = \Bxmaker\AuthUserPhone\Manager::CONFIRM_TYPE_SMSCODE;
$confirmValue = '0156'
$confirmResult = $oManager->checkConfirm($phone, confirmType, $confirmValue);

Этот метод на вход получает данные по проверке и в зависимости от прохождения возвращает объект Result не содержащий или содержащий ошибку. Этот объект можно передавать на вход другим методам таким как forgot(), register()

$result = $oManager->forgot($phone, $email, $confirmResult);
if ($result->isSuccess()) {
    // успех
} else {
    //обработка ошибок
}

или использовать самостоятельно:

if ($confirmResult->isSuccess()) {
    // успех
} else {
    //обработка ошибок
}

Авторизация по номеру телефона

Метод loginByPhone() используется для авторизации или регистрации пользователя. Здесь есть несколько вариаций логики метода.

  1. Если пользователь существует. Если введены логин и пароль верные - происходит авторизация пользователя. Если введены номер телефона и верный временный код - происходит авторизация.

Если пользователь авторизован при помощи временного кода, и в настройках стоит соответствующая галочка, то вызывается метод setPassword().

  1. Если пользователь не существует. Если введены номер телефона и верный временный код - происходит регистрация пользователя и авторизация. Вызывается метод register().

В описании указаны вызываемые методы, так как в них вызываются соответствующие события. В результате работы метода возвращается объект класса Result.

В случае наличия ошибок в подробной информации об ошибке можгут содержаться данные для вывода капчи, если требуется ее ввод (получаемые от метода getCaptchaForErrorMore() ). Там будет находится среди прочего NEED_CAPTCHA=true

$res = $oManager->loginByPhone($phone = '8 999 111 22 33', $passwor_or_code = '0000', $remember = false);

if($res->isSuccess())
{
   echo $res->getMore('MSG');
  echo $res->getMore('REDIRECT'); // добавляется в случае надобности, ссылка на страницу профиля пользователя для заполнения
  
}
else
{
  // ошибка валидности номера телефона
  // ошибка длина пароля, временного кода не менее 4 символов, 
  // ошибка без описания, ERROR_PHONE_IS_LOGIN,  возникает в случае если номер логин = номер телефона, при этом в настройках модуля хранение номера телефона указывает на другое поле
  // ошибка не верный временный код
  // ошибка не верный номер телефона или пароль
  // ошибка необходимости наличия данных капчи

   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
      
   }
}

Авторизация общая по номеру телефона, логину, email адресу

Метод login() используется для авторизации по номеру телефона, логину или email адресу пользователя. В первой части метода вызывается метод loginByPhone(), поэтому повторно описываться этой части логика не будет.

Если не удалось авторизовать пользователя по номеру телефона, то производится попытка уже авторизации по логину или email адресу.

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

$res = $oManager->login($phoneLoginEmail = '8 999 111 22 33', $passwor_or_code = '0000', $remember = false);

if($res->isSuccess())
{
   echo $res->getMore('MSG');
  echo $res->getMore('REDIRECT'); // добавляется в случае надобности, ссылка на страницу профиля пользователя для заполнения
  
}
else
{
  // ошибка валидности номера телефона
  // ошибка длина пароля, временного кода не менее 4 символов, 
  // ошибка без описания, ERROR_PHONE_IS_LOGIN,  возникает в случае если номер логин = номер телефона, при этом в настройках модуля хранение номера телефона указывает на другое поле
  // ошибка не верный временный код
  // ошибка не верный номер телефона или пароль
  // ошибка необходимости наличия данных капчи

 //к прочим ошибкам, которые появляются из метода loginByPhone() появляется дополнительная с информацией от главного модуля, класса \CUser


   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {
     
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
      
   }
}

Регистрация пользователя

Метод register() используется для регистрации пользователя по номеру телефона, с вызовом в процессе события onUserAdd.

  • Если пароль не задан, то он будет сгенерирован.
  • Если логин не задан, будет использован номер телефона в качестве логина.
  • Если email не задан, то будет при регистрации установлен временный email, который после добавления пользователя будет удален.
  • И соответственно массив дополнительных полей, которые необходимо заполнить при добавлении пользователя.
$res = $oManager->register(
   $phone = '8 999 111 22 33',
   $pass = null, 
   $login = null,
   $email = null,
   $arUserFields = array(),
   $arUserConsent = array(),
   \Bxmaker\AuthUserPhone\Result $confirmResult = null
);

if($res->isSuccess())
{
    $userId = $res->getResult();  
}
else
{
  // ошибка не верно введенного номера телефона
  // ошибка длины пароля
  // Прочие ошибки, получаемые от модуля \CUser во время добавления пользователя
   
   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {     
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
      
   }
}

Восстановление доступа по номеру теелфона или email

Для этих целей используется метод forgot(). При восстанволении по email сразу отправит письмо с ссылкой на моментальную авторизацию. А при восстановлени по номеру телефона в зависимости от настроек запроит подтверждение номера смс или звонком и при успешном подтверждении сразу авторизует на сайте.

$email = null;
$phone = '7(999)111-22-33';
$confirmType = \Bxmaker\AuthUserPhone\Manager::CONFIRM_TYPE_SMSCODE;
$confirmValue = '0156'

$confirmResult = $oManager->checkConfirm($phone, confirmType, $confirmValue);

$result = $oManager->forgot($phone, $email, $confirmResult);
if ($result->isSuccess()) {
    // успех
} else {
    //обработка ошибок
}

Отправка письма для восстановления доступа на почту

Метод sendEmail() - используется для отправки письма на почту пользователю, для восстановления доступа.

$res = $oManager->sendEmail($loginEmail = '7 999 11-22-33');
if($res->isSuccess())
{
    echo $this->getMore('MSG'); // почтовое сообщение успешно отправлено
}
else
{
  // ошибка отсутствия капчи
  // ошибка отсутствия логина или email
  // ошибка отключена возможность восстановления доступа по email

   $arErrors = $res->getErrors();
   foreach($arErrors as $obError)
   {     
       echo $obError->getMessage();
       echo $obError->getCode();
       echo '<pre>';
       print_r($obError->GetMore());
       echo '</pre>';
      
   }
}

Метод для генерации контрольной строки для восстановления доступа

Метод getUserAccessRestoreHash() используется для генерации контрольной строки, используемой для подписи ссылки отправляемой в почтовом сообщении.

$hash = $oManager->getUserAccessRestoreHash(
   $userId = 12,
   $timestamp = 35666546, // получен с помощью time()
   $password = JFWJoFWOI..JOFJW, // поле PASSWORD из базы данных конкретного пользователя
   $checkword = WFO..FJPW, // аналогично поле CHECKWORD,
   $salt = null // случайная строка для использования при генерации хэш значений
 );