Подтверждение номера телефона юзера после регистрации

Главные вкладки

Аватар пользователя denserdv denserdv 13 января 2014 в 23:17

Здравствуйте!

Есть задача - запрашивать у пользователя номер телефона с проверкой его через смс. При успешной проверке номера присваивать юзеру роль.
Саму проверку я могу сделать.

Не придумалось (весь день промаялся) как запрашивать с юзера этот номер телефона..

Мысли такие -
1) создать в профиле поле "номер телефона"
2) создать также в профеле поле "введите проверочный код"
3) при сохранении профиля проверять номер телефона. Проверяется легко вот такой строкой (через смс-сервис, где я уже зарегистрирован):

 file_get_contents("http://sms.ru/sms/send?api_id=мой_ид&to=$user_phone&text=$code");
 // где $user_phone - это то, что юзер ввел в поле "номер телефона", а $code - это код, который ему пришел в смс.

Так вот, если юзер получил на свой телефон код и ввел его в это поле (а я знаю чему равен код) - я определяю что номер телефона вбит реальный.

4) рулесами присваивать роль при заполнении поля "номер телефона".

Вот, собственно, я никак не придумал как же спрашивать с юзера проверочный код??
- если создать в профиле поле - то какого типа? я не нашел поле в котором можно пхп вставлять. И при этом надо чтобы скрипт начал проверять код уже после введения номера телефона - т.е. скорее всего после нажатия кнопки "сохранить" в профиле юзера и если номер телефона неверный (или введенный код) - то опять надо показывать редактирование профиля.
- если делать в рулесах проверку - там я пробовал создать правило, в котром указано что при обновлении профиля юзера, если произошло такое-то условие, выполнить смену роли. В условии можно вписать пхп-скрипт. Но я не понял как его делать... тем более что здесь мне нужно будет как раз запрашивать с юзера ввод проверочного кода.

Может вообще не туда копаю?

Подскажите пожалуйста как делать. В я не программист, поэтому просто свой модуль не пишу. Общие понимания имею Smile

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

РЕШЕНО
- Спасибо всем, кто отвечал в данной теме. Мое решение таки не обошлось без создания модуля с помощью программистов. Его код и выкладываю - вдруг кому пригодится.

***

Внимание! Позже я переработал код и сделал все по другому, об этом написал в комментарии: http://www.drupal.ru/node/106770#comment-596597 . Мне новый вариант больше нравится, но первый вариант, с недоработанным модулем тоже оставил здесь.

***

И так, принцип действия у меня на сайте такой:
1) пользователь регистрируется на сайте, заполняя только емаил (делается установкой модуля https://drupal.org/project/email_registration )
2) после такой регистрации, юзеру уходит письмо с одноразовой ссылкой на вход. Юзер переходит по ней и попадает в редактирование своего профиля. Заполняет пароль и поле "номер телефона".
Для работы модуля в профиле юзера нужно два поля - "номер телефона" и "проверочный код".
3) Юзер жмет "сохранить" и тут срабатывает наш модуль - он отправляет смс на введенный номер телефона со сгенерированным кодом.
4) Получив в смс проверочный код, юзер вносит его в соответствующее поле в своем профиле (профиль юзера в данный момент еще открыт на редактирование)
5) Юзер жмет "сохранить" и если введенный код совпадает, то юзеру устанавливается роль "подтвержденный телефон". Если не совпадает - выводится сообщение чтобы ввёл верный код.
(в коде модуля указан ИД нужной роли - в строке
$edit['roles'][3]=true;
- Вы поставьте свой ИД нужной роли.

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

И так, кому нужен код модуля - привожу его здесь см. вложенный файл.
(напоминаю, данному модулю нужны поля в профиле юзера: номер телефона и проверочный код. А также роль "подтвержденный телефон")

Модуль достаточно простой - сможете доделать под себя. Я просто описал как он работает у меня. Никакой ответственности не несу - предоставлю код как есть Smile - в модуле отстутствуют ненужные мне проверки на валидность введенного номера телефона, на защищенность генерируемого кода и т.п. Мне они не нужны в данном случае.
Рассуждения об этом можно посмотреть в комментарии: http://www.drupal.ru/node/106770#comment-594490

Ставится модуль как и все обычные модули.

Да, в модуле есть строка:

@file_get_contents("http://sms.ru/sms/send?api_id=ВАШ_ИД&to=".$edit['field_telnum']['und'][0]['value']."&text=".$edit['field_hcode']['und'][0]['value']);

- здесь вместо ВАШ_ИД вставьте свой ID, полученный в системе sms.ru
подробнее здесь: http://sms.ru/?panel=api&subpanel=method&show=sms/send

Ну и соответственно, если будете использвоать сервис отправки смс не sms.ru, то вместо данной строки впишите свой код.

Кому не нужно устанавливать роль юзеру после подтверждения номера - уберите соотвествующую функцию.

Комментарии

Аватар пользователя Orion76 Orion76 13 января 2014 в 23:35

НЕдавно выложил модуль для рассылки смс, как раз через sms.ru
http://www.drupal.ru/node/106566
В общем, основная цель была, собрать иннформацию, какой функционал еще наиболее востребован..
Если убедите, что Ваша проблема достойна решения, добавим нужный функционал..

Аватар пользователя denserdv denserdv 14 января 2014 в 1:24

Извините, я не понял из описания этого модуля... вот из описания его настройки:
6.В поле PHONE NUMBER вводим свой телефон(без пробелов, первая-7: 792712312323)
7.Как только пользователь blondinko111 зайдет на сайт, на ваш телефон придет смс.

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

"orion76" wrote:
Если убедите, что Ваша проблема достойна решения, добавим нужный функционал..

- ну я думаю найдется много сайтов, которым нужна проверка введенных данных не только на валидность, но и на "реальность". Много какие сайты собирают контактную инфу с пользователей, включая телефонные номер - магазины, сайты по инфобизнесам и т.п.

Аватар пользователя Orion76 Orion76 14 января 2014 в 1:40

"denserdv" wrote:
- так смску можно только на свой телефон получать?

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

Да.. с проверочным кодом сложнее..
Его надо сгенерировать, сохранить в базу, отправить пользователю, получить ответ и т.д..
Надо поискать, может уже есть модули, реализующие что-то подобное хотябы при помощи email..
Возможно надо будет доработать только способ отправки сообщения и получения ответа..

Аватар пользователя denserdv denserdv 14 января 2014 в 9:55

"orion76" wrote:
Его надо сгенерировать, сохранить в базу, отправить пользователю, получить ответ и т.д..

- я видел для вордпресса модуль - там хитро сделано - взяли введенный емаил юзера, закодировали в md5 и записали в куку. Это все в скрипте формы регистрации.
Получившийся код (закодированный мд5 емаил) отправили в смске юзера.
При нажатии кнопки "сохранить" в вордпрессе грузится этот же скрипт авторизации, где продолжение скрипта - он смотрит что есть отправленные данные и кука существует. Если так - то проверяет значение куки с тем, что юзер ввел в поле "проверочный код".
Если нет куки или она не соответствует введенному коду - то редирект на форму регистрации.

обошлись без баз и т.п. Все просто.

Вот как бы в друпале провернуть похожую схему...

Аватар пользователя Dalay Dalay 14 января 2014 в 10:20

"denserdv" wrote:
Вот как бы в друпале провернуть похожую схему...

Да элементарно. Через hook_form_FORM_ID_alter(или hook_form_alter) преобразовываете форму регистрации в "многошаговую". После первого этапа генерируете, записываете (в куки или в сессию) и отсылаете на мобилу код. На последнем шаге этот код сверяете.

Аватар пользователя denserdv denserdv 16 января 2014 в 13:35

Спасибо всем за подсказки. Я выкладываю свое решение в самом посте и переименую название поста, так как после полученного решения - сам пост приобрел более конкретное название Smile

Аватар пользователя Dalay Dalay 16 января 2014 в 16:59

"denserdv" wrote:
Я выкладываю свое решение...

"Решение" Ваше никуда не годится.
Во-первых, оно насквозь дырявое. Проверочный код, никак не закодированный, открыто лежит в куке и значении поля с кодом, которое скрыто просто через "display:none"(это ваще на пять))).

Во-вторых, создавать отдельное, полноценное поле под проверочный код (который используется лишь однажды) это, мягко скажем, не умно. Как и использование для валидации значений формы и ее(формы) дополнительной обработки hook_user_presave, вместо
специально для оных действий предназначенных функций Form API.

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

В-четвертых, нет никаких проверок на то, что введен действительно телефонный номер, и смс с кодом было реально отправлено. Т.е., при любом раскладе(после ввода и отправки "телефона") пользователь увидит сообщение о том, что смс с кодом ему ушло.

И в-последних, при назначении пользователю новой роли используется конкретный индекс роли(3, в Вашем случае). У того, кто, возможно, решит воспользоваться выложенным модулем, индекс этот необязательно будет тем же.

Аватар пользователя denserdv denserdv 16 января 2014 в 18:22

Ну так я сразу сказал что выложил то, что используется у меня и надо ИД менять.

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

Также я сказал что решение простое и делалось программистами по просьбе сделать максимально просто и быстро.

Если юзер ввел не номер телефона а непонятно что - его проблемы - код не получит, значит не введет и значит не включится роль и не будет созвона с менеджером Smile
А кому надо все првоерять досконально- код модуля простой и понятный даже мне - не программисту Smile - в функциях можно дописать все какие хотите проверки.

Вот как-то так Lol

Аватар пользователя denserdv denserdv 16 января 2014 в 18:29

"denserdv" wrote:
"Решение" Ваше никуда не годится.

- но за критику большое спасибо. Учту когда понадобиться усоврешенствовать модуль. И заодно наши рассуждения прочтут другие не-программисты и сразу поймут недоработки и доделают если будет надо. К тому же в самом посте я еще добавил уточнений.

Лично я был бы рад , если бы кто-то выложил такой модуль - я бы смог произвести доработки проверки валидации номера телефона и может еще какие-нибудь. Но я ничего такого не нашел и заказывал программистам. А потом такой "сырой" вариант и выложил - чтобы другие смогли его взять и доработать под себя.

Аватар пользователя denserdv denserdv 29 января 2014 в 16:26

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

сам код я просто вставил прямо в текст ноды , выбрав фильтр "пхп-код".

Мне нравится как работает - и код подтверждения каждый раз разный и не хранится в куках он. Для временной передачи от формы к форме использую сессии.
Для работы модуля, надо создать в профиле юзера поле "номер телефона" (машинное имя field_telnum. если у вас другое - не забудьте изменить в коде) - скрипт сюда и сохраняет телефон.
ВОт код:


<?php
global $user;

  

$userID $user->uid;
  
$user user_load($userID); // надо загрузить все переменные профиля юзера
   
  
$f_telnumber '<form name="telnumform" id="telnumform" action="" method="post">
                    <p>
                        <label for="user_phone">Введите Ваш номер телефона:<br />
                            <input type="text" name="user_phone" id="user_phone" class="input_phone" value="" size="20" /></label><br />
                            <span class="help">Номер телефона вводите в формате +7 999 999 99 99 <br />(всего 10 цифр и знак + , можно без пробелов )</span>
                    </p>
                    <input type="submit" name="submit_phone" id="submit_phone" class="button button-primary button-large" value="Отправить" />
                </form>'
;
                
 if(
$_POST)
  {     
        if (isset(
$_POST['user_phone'])) {$user_phone $_POST['user_phone'];}
        
        
$user_phone str_replace(' ','',$user_phone);
        
            
$f_telnumber_cod '<form name="telnumform_confirm" id="telnumform_confirm" action="" method="post">
                            <p>
                                <label for="user_confirm">Введите код подтвержения:<br />
                                    <input type="text" name="user_confirm" id="user_confirm" class="input" value="" size="20" /></label>
                            </p>
                            <input type="submit" name="submit_phone_confirm" id="submit_phone_confirm" class="button button-primary button-large" value="Отправить" />
                            <input type="submit" name="resubmit_phone" id="resubmit_phone" class="button button-primary button-large" value="Отправить код еще раз" />
                            <input type="hidden" name="user_phone" id="user_phone" value='
.$user_phone.' />
                            <input type="hidden" name="submit_phone" id="submit_phone" value="" />
                    </form>'
;
                            
        if (isset(
$_POST['submit_phone']) && !isset($_POST['submit_phone_confirm'])) 
          {
            if( 
$user_phone == '' )
            {
                echo 
'<p class="error_txt"><strong>ОШИБКА</strong>: Введите номер телефона!</p>';
                echo 
$f_telnumber//выводим форму с полем для вставки номера телефона
            
}
            else
            {
             
$_SESSION['code'] = generateText(); //создаем сессию для временного хранения кода подтверждения
             
                     //отправляем команду на отправку смс через sms.ru - надо там зарегиться для этого
                     
@file_get_contents("http://sms.ru/sms/send?api_id=ВАШ_ИД&to=".$user_phone."&text=".$_SESSION['code']);

                    echo 

$f_telnumber_cod//выводим форму с полем для вставки кода подтверждения
            
}
          }
        else
        {
          if (isset(
$_POST['submit_phone_confirm'])) 
           {
            
$user_confirm $_POST['user_confirm'];
            
$user_phone $_POST['user_phone'];
            
$code $_SESSION['code'];
              if ( 
$user_confirm == '' 
              {
                echo 
'<p class="error_txt"><strong>ОШИБКА</strong>: Введите код подтверждения</p>';
                echo 
$f_telnumber_cod//выводим форму с полем для вставки кода подтверждения
              
}
              else if(
$code != $user_confirm)
              {
                echo 
'<p class="error_txt"><strong>ОШИБКА</strong>: Введите верный код подтверждения</p>';
                echo 
$f_telnumber_cod//выводим форму с полем для вставки кода подтверждения
              
}
              else
              {
                
                if(
$user->uid 0
                {
                
$user_phone str_replace(' ','',$user_phone);
                unset(
$user->roles[2]); // если надо у юзера снять какую-то роль - указать ИД этой роли
                
$user->roles[9]= true// если надо юзеру установить какую-то роль - указать ИД этой роли
                
$user->field_telnum['und'][0]['value'] = $user_phone// вписываем номер телефона в профиль юзера
                
user_save($user); // сохраняем в профиль юзера указанные выше данные (роли, телефон)
                
                
echo "<br />Номер телефона добавлен: ".$user_phone;
                }
                else {
                  echo 
'<p class="error_txt">Вы не авторизованы! Для авторизации перейдите по ссылке <a href="http://ваш_сайт.ru/user">http://ваш_сайт.ru/user</a> </p>';
                }
              }
           }
        }

  } else {
            echo 

$f_telnumber;
  }

  

// функция генерации кода подтверждения из 5 символов, мелкие латинские буквы
  
function generateText($length=5){
    
$passwordChars = array(
        
'q','w','e','r','t','y','u','i','o','p',
        
'a','s','d','f','g','h','j','k','l',
        
'z','x','c','v','b','n','m',
    );
    
srand((float)microtime() * 100000);
    
shuffle($passwordChars);
    
$random array_rand($passwordChars,$length);
    
$password '';
    foreach (
$random as $key){
        
$password .= $passwordChars[$key];
    }
    return 
$password;
  }

?>