现在许多APP都采用手机号+短信验证码,来实现注册登陆操作。这样不仅大大减化了用户的操作,用户还不用担心忘记密码。
功能分析
为防止接口被恶意调用,造成不必要的经济损失,我们制定了几条规则:
- 同一手机两次发送间隔时间1分钟(可配置间隔时间)
- 同一手机1小时内最多只能发送3次验证码(可配置发送次数)
- 验证码为4位随机数字,采用 Memcache 缓存
- 验证码有效时间:5分钟(可配置时间)
- 多次发送验证码,只有最后一次有效
- 验证码为一次验证,验证成功后,立即失效
创建接口
请求类型:POST
接收参数:user_mobile
(手机号)
- 在
/app/controllers/
目录下创建文件SmsController.php
, 并插入代码:
<?php
class SmsController extends BaseController
{
/**
* 发送短验证码
*/
public function sendAction()
{
}
}
- 发送短信接口不需要进行身份认证(TOKEN),在
/app/config/config.php
中的authentication.exclude
下追加元素sms/send
, 如:
'authentication' => [
'enable' => 1, // 身份认证: 0 关闭, 1 激活
'single' => 0, // 单点登录: 0 允许多个客户端同时登录; 1 同一时间,只请允许最后登录设备使用
// 身份认证排除页面
'exclude' => [
'sms/send',
]
],
- 验证请求类型是否为 POST。在
/app/controllers/BaseController.php
中添加函数isPost()
, 如:
/**
* 验证请求方法是否是
*/
public function isPost()
{
if (!$this->request->isPost()) {
Output::instance($this->response)->fail('请求接口不存在', 404);
}
}
- 在
/app/controllers/SmsController.php
的函数sendAction()
中添加代码:$this->isPost();
, 如:
public function sendAction()
{
// 验证请求方法是否是POST
$this->isPost();
}
验证请求参数
我们以
Phalcon
的一个独立的组件Phalcon\Validation
做为基出,对客户端提交的数据进行验证。官方文档
- 重写基础验证类
XValidation
。在/app/library
目录下创建基础验证类文件XValidation.php
, 并添加代码:
<?php
use Phalcon\Validation;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Regex;
/**
*
* 重写验证类
*/
class XValidation extends Validation
{
/**
* 获取验证失败信息
* @return mixed
*/
private function getMessage()
{
foreach (parent::getMessages() as $message) {
return $message->getMessage();
}
}
/**
* 验证操作,未通过直接输入失败信息
* @param $params
* @return bool
* @throws Exception
*/
public function valid($params)
{
$messages = $this->validate($params);
if (count($messages) > 0) {
throw new Exception($this->getMessage());
}
return true;
}
}
Phalcon\Validation
内置失败信息是一个对象,包括了许多并不常用的信息。我们创建函数getMessage()
, 来直接获取验证失败信息,以方便验证时使用。- 由于我们系统创建的时候,就已经做好了异常拦截操作。所以,我们在这里创建一个验证执行函数
valid()
, 当验证未能过时,直接将错误信息通过异常抛出,再由异常拦截器将错误信息返回给接口。
参考:「PHP开发APP接口实战003」自定义异常处理
- 为控制器
SmsController
创建验证类XValidationSms
, 并为sendAction()
创建对应的验证函数send()
,如:
<?php
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Regex;
/**
*
* 发送短信参数验证
*/
class XValidationSms
{
/**
* 发送短信参数验证
* @param $params
* @return bool
* @throws Exception
*/
public static function send($params)
{
$validation = new XValidation();
$validation->add('user_mobile', new PresenceOf(['message' => '缺少手机号码']));
$validation->add('user_mobile', new Regex(['message' => '无效手机号码', 'pattern' => '/^1[34578]{1}\d{9}$/']));
return $validation->valid($params);
}
}
- 引用了两个内置验证器:
Phalcon\Validation\Validator\PresenceOf
(检测是否为空)Phalcon\Validation\Validator\Regex
(正则表达式验证)
更多 Phalcon 内置验证器文档
- 实例化前面自定义的验证类
Validate
, 并增加验证规则:
- 检测手机号是否为空
- 检测手机号格式是否正确
- 调用验证函数
valid()
- 在
sendAction()
中调用对应的验证函数send()
,实现验证请求参数。如:
// 验证请求参数
XValidationSms::send($this->getPost());
这里只需要调用验证函数, 不需要接收验证状态,如验证未通过,会自动抛出错误信息,并终止程序。
SmsController.php
完整代码:
<?php
class SmsController extends BaseController
{
/**
* 发送短验证码
*/
public function sendAction()
{
// 验证请求方法是否是POST
$this->isPost();
// 验证请求参数
XValidationSms::send($this->getPost());
}
}
示例代码下载
链接:https://pan.baidu.com/s/1gvyi8eX3JdlEUzzndpLVoQ 密码:839z