PHP实战PHP经验分享Phalcon

「PHP开发APP接口实战011」发送短信验证码之参数验证

2018-03-05  本文已影响51人  一念觀心

现在许多APP都采用手机号+短信验证码,来实现注册登陆操作。这样不仅大大减化了用户的操作,用户还不用担心忘记密码。

功能分析

发送短信验证码流程图

为防止接口被恶意调用,造成不必要的经济损失,我们制定了几条规则:

  • 同一手机两次发送间隔时间1分钟(可配置间隔时间)
  • 同一手机1小时内最多只能发送3次验证码(可配置发送次数)
  • 验证码为4位随机数字,采用 Memcache 缓存
  • 验证码有效时间:5分钟(可配置时间)
  • 多次发送验证码,只有最后一次有效
  • 验证码为一次验证,验证成功后,立即失效

创建接口

请求类型:POST
接收参数:user_mobile(手机号)

  1. /app/controllers/ 目录下创建文件 SmsController.php, 并插入代码:
<?php

class SmsController extends BaseController
{

    /**
     * 发送短验证码
     */
    public function sendAction()
    {

    }
}

接口地址:http://127.0.0.1:20081/sms/send

  1. 发送短信接口不需要进行身份认证(TOKEN),在 /app/config/config.php 中的 authentication.exclude 下追加元素 sms/send, 如:
    'authentication' => [
        'enable' => 1,  // 身份认证: 0 关闭, 1 激活
        'single' => 0, // 单点登录: 0 允许多个客户端同时登录; 1 同一时间,只请允许最后登录设备使用
        // 身份认证排除页面
        'exclude' => [
            'sms/send',
        ]
    ],
  1. 验证请求类型是否为 POST。在 /app/controllers/BaseController.php 中添加函数 isPost(), 如:
    /**
     * 验证请求方法是否是
     */
    public function isPost()
    {
        if (!$this->request->isPost()) {
            Output::instance($this->response)->fail('请求接口不存在', 404);
        }
    }
  1. /app/controllers/SmsController.php 的函数 sendAction() 中添加代码:$this->isPost();, 如:
    public function sendAction()
    {
        // 验证请求方法是否是POST
        $this->isPost();
    }

验证请求参数

我们以 Phalcon 的一个独立的组件 Phalcon\Validation 做为基出,对客户端提交的数据进行验证。官方文档

  1. 重写基础验证类 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;
    }

}
  1. Phalcon\Validation 内置失败信息是一个对象,包括了许多并不常用的信息。我们创建函数 getMessage(), 来直接获取验证失败信息,以方便验证时使用。
  2. 由于我们系统创建的时候,就已经做好了异常拦截操作。所以,我们在这里创建一个验证执行函数 valid(), 当验证未能过时,直接将错误信息通过异常抛出,再由异常拦截器将错误信息返回给接口。
    参考:「PHP开发APP接口实战003」自定义异常处理
  1. 为控制器 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);
    }
}
  1. 引用了两个内置验证器:
  1. 实例化前面自定义的验证类 Validate, 并增加验证规则:
  • 检测手机号是否为空
  • 检测手机号格式是否正确
  1. 调用验证函数 valid()
  1. 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

上一篇下一篇

猜你喜欢

热点阅读