Cómo Verificar un Número de Teléfono vía SMS
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)



Introducción
En el episodio anterior, escribí sobre preparar tu aplicación para SMS usando Twilio, un servicio de mensajes de texto comúnmente usado. En el tutorial de hoy, te mostraré cómo verificar números de teléfono de usuario antes de transmitir un volumen alto de textos y elevar tus costos.
Antes de que comencemos, quiero alentarte a publicar preguntas y retroalimentación en los comentarios. Si quisieras estar al tanto de mis futuros tutoriales Envato Tuts+ y otras series, por favor visita mi página de instructor o sigue a @lookahead_io.
Delineando el Proceso
Después de que el usuario proporciona su número de teléfono, queremos realizar un puñado de pasos sencillos:
- Genera un código único de 4 dígitos.
- Almacena su número de celular y el código de cuatro dígitos en nuestra base de datos (o encripta el código de manera local como una variable oculta de formulario en la página).
- Envía un texto al número no verificado con el código de cuatro dígitos.
- Muestra un formulario pidiendo al usuario proporcionar el código que recibieron.
- Verifica que los códigos empaten.
- Designa el número como verificado en la base de datos.
La Página de Contacto del Usuario
En Planificador de Reuniones, cada usuario puede agregar múltiples métodos de contacto, ej. Skype, teléfono, etc. Cada número celular debe ser verificado para ser usado para notificaciones SMS.
La tercera fila de abajo muestra una casilla a la que pueden dar clic para solicitar verificación:



Dar clic a eso transfiere al usuario al controlador actionVerify() de abajo; nota que los lleva al bloque else al principio porque aún no han enviado código:
1 |
public function actionVerify($id) |
2 |
{
|
3 |
$model = $this->findModel($id); |
4 |
if ($model->load(Yii::$app->request->post())) { |
5 |
...
|
6 |
} else { |
7 |
$canRequest = $model->canRequest(); |
8 |
if ($canRequest) { |
9 |
// send a text to this number
|
10 |
$model->requestCode(); |
11 |
return $this->render('verify', [ |
12 |
'model' => $model, |
13 |
]);
|
14 |
} else { |
15 |
Yii::$app->getSession()->setFlash('error', $canRequest); |
16 |
return $this->redirect(['/user-contact']); |
17 |
}
|
18 |
}
|
19 |
}
|
El método canRequest() revisa si han solicitado códigos repetidamente o demasiado frecuentemente.
1 |
public function canRequest() { |
2 |
if ($this->request_count<UserContact::MAX_REQUEST_COUNT) { |
3 |
if (time() - $this->requested_at>=60) { |
4 |
return true; |
5 |
} else { |
6 |
return Yii::t('frontend','Sorry, you must wait a minute between requests.'); |
7 |
}
|
8 |
} else { |
9 |
return Yii::t('frontend','You have exceeded the maximum number of attempts.'); |
10 |
}
|
11 |
}
|
Los hago esperar un minuto entre intentos para reducir abuso.
Transmitiendo el Código de Verificación
Si es permitido, este llama a requestCode():
1 |
public function requestCode() { |
2 |
$this->verify_code = rand(0,9999); |
3 |
$this->requested_at = time(); |
4 |
$this->request_count+=1; |
5 |
$this->update(); |
6 |
$sms = new Sms; |
7 |
$sms->transmit($this->info,Yii::t('frontend', |
8 |
'Please return to the site and type in {code}',['code'=>sprintf("%04d",$this->verify_code)])); |
9 |
}
|
Esto hace lo siguiente:
- Genera un código aleatorio de cuatro dígitos.
- Registra el último momento en tiempo (segundos unix) que una petición a verificar fue hecha.
- Incrementa los intentos de verificación para este número.
- Y almacena todo esto en la base de datos.
- Después, transmite un texto con el código que luce como la imagen de abajo.



Después de solicitar el código, guardarlo en la base de datos tras bambalinas y transmitir el código al usuario, este carga el siguiente formulario pidiendo el código:



Verificando el Código
Cuando el usuario intenta enviar un código, este ejecuta la parte superior de actionVerify():
1 |
public function actionVerify($id) |
2 |
{
|
3 |
$model = $this->findModel($id); |
4 |
if ($model->load(Yii::$app->request->post())) { |
5 |
// display verification form |
6 |
$model->verify = Yii::$app->request->post()['UserContact']['verify']; |
7 |
if (strval($model->verify_code) == strval($model->verify)) { |
8 |
$model->status = UserContact::STATUS_VERIFIED; |
9 |
$model->update(); |
10 |
Yii::$app->getSession()->setFlash('success',Yii::t('frontend','Thank you, your number is confirmed.')); |
11 |
return $this->redirect(['/user-contact']); |
12 |
} else { |
13 |
Yii::$app->getSession()->setFlash('error', Yii::t('frontend','Sorry, that is incorrect. Please request a new code.')); |
14 |
return $this->redirect(['/user-contact']); |
15 |
}
|
16 |
} else { |
17 |
...
|
18 |
}
|
19 |
}
|
Este revisa que todos los códigos empaten. Si lo hacen, actualiza la base de datos para reflejar que el número ha sido verificado. Y le dice al usuario:



Si no, muestra un mensaje de error:



Inténtalo Tu Mismo
Si quieres ver esto en acción, puedes registrarte en Simple Planner o Planificador de Reuniones (que es sencillo con una cuenta social como Facebook o Google) y agrega un número de teléfono. Después da clic a la casilla de verificación que la lista que verás. Eso es todo.
Concluyendo
Obviamente, si tu aplicación manda muchos mensajes de texto, es un costo notable para el negocio, y quieres limitar el abuso. Eso comienza con establecer un cortafuegos contra números inválidos---o números válidos que no pertenecen realmente al impostor.
Espero que esto te haya sido de utilidad. Si tienes cualquier pregunta o sugerencia, por favor postealas en los comentarios. Si quisieras estar al tanto de mis tutoriales Envato Tuts+ futuros y otras series, por favor visita mi página de instructor o sigue a @lookahead_io. Definitivamente revisa mi serie startup y Planificador de Reunión.



