很多团队做后台或官网时,注册、登录、找回密码都离不开短信验证码。用ThinkPHP5(下文简称tp5)开发的项目,接入阿里云短信服务是比较常见的选择。接口规整,走国内运营商通道,到达率一般可以接受。这篇文章按顺序讲一遍:从控制台开通,到代码落地,最后用一个登录验证码的例子把关键点串起来。

一、控制台要先配好
这部分和代码没有直接关系,但很多验证码发不出去的问题恰恰出在这里,而且接口返回的报错往往不直观。开通之前,先把下面几样弄清楚:
- 开通短信服务(Short Message Service),进入控制台后按需选择国内消息或国际消息。
- 创建签名。签名要和企业或网站名称一致,需要上传营业执照等材料。审核一般要几个小时,慢的时候会拖到一两个工作日,所以别等到上线前一天才提交。
- 创建模板。模板里要有变量,比如“您的验证码为${code},5分钟内有效。”模板同样要审核,而且不能混进与验证码无关的营销内容,否则很容易被打回。
- 获取AccessKey。建议单独建一个RAM子账号,只给短信相关权限。主账号密钥一旦泄露,损失会大得多。
配置完成后,手里应该有四样东西:签名名称、模板CODE、AccessKeyId和AccessKeySecret。后面代码里用到的关键参数就是它们。抄错一个字符,排查时很容易绕远路。
二、安装SDK
tp5项目一般用Composer管理依赖。阿里云提供了PHP SDK,在项目根目录执行:
composer require alibabacloud/sdk
安装完成后,vendor目录里会出现自动加载文件。装之前先确认PHP版本,SDK一般要求PHP 7.1及以上。版本太低时,报错未必会指向版本问题,很容易误以为是代码写错了。
三、把发送逻辑封装成服务类
建议把短信发送单独封装成一个类,放在application/common/service目录下。控制器只管业务流程,不用关心SDK的调用细节,以后换模板或加日志也只改一处。
文件路径:application/common/service/SmsService.php
这个类主要做三件事:读取配置、组装请求参数、调用SDK发送,并根据返回结果判断成功与否。配置项统一放在config/sms.php里,不要把AccessKey写死在代码中。日志和异常处理可以按项目需要再补充。
四、验证码的生成、存储与校验
发出去只是第一步。验证码怎么生成、存在哪里、什么时候失效,同样影响体验和安全。常见做法有以下几点:
- 用随机数生成6位数字验证码,别用时间戳或自增序列,那样很容易被猜出来。
- 把验证码和手机号绑定后存入缓存,比如Redis,过期时间设成5分钟左右,和短信模板里的文案保持一致。
- 同一手机号做发送频控,例如60秒内只能发一次,每天设上限。没有这层限制,短信接口很容易被刷。
- 校验通过后立刻删除缓存里的验证码,保证一码只能用一次。
五、以登录页为例
假设某电商后台要支持手机号验证码登录。流程并不复杂:用户输入手机号,点击获取验证码,服务端校验格式和发送频率,生成验证码并调用短信服务,用户输入验证码后完成登录。
控制器里发送接口的处理顺序最好固定下来:先校验手机号,再检查频率限制,然后生成验证码写入缓存,最后调用短信类发送。如果发送失败,要把刚写入的验证码从缓存里删掉。否则用户没收到短信,缓存里却留着一个没送达的码,既混乱又埋下隐患。
上线后重点盯两个数字:短信送达率和验证码校验成功率。送达率偏低,多半与签名、模板的审核状态或运营商拦截有关。校验失败多,先看缓存过期时间是否合理,再确认前端传过来的验证码是否正确。
六、常见报错和容易踩的坑
- 返回“isv.BUSINESS_LIMIT_CONTROL”,说明触发了频控。先降低调用频率,再检查限流规则是否配得太严。
- 返回“isv.SMS_SIGNATURE_ILLEGAL”,通常是签名没过审,或者代码里的签名名称和控制台不一致。两边对一下,大多能解决。
- 模板变量的格式必须和提交审核时完全一致,多一个空格都可能导致发送失败。
- 测试阶段尽量用阿里云提供的测试手机号,既不产生真实费用,也不会打扰真实用户。
接口本身也要做防刷。短信接口如果不设限,脚本很快就能批量调用,账单会迅速增长。可以结合图形验证码或风控策略,对发送接口做多层保护。哪怕只是一个登录页,这一步也不宜省略。
七、收尾
tp5接入阿里云短信的流程其实就几步:先把控制台配置对齐,再封装SDK发送逻辑,最后处理好验证码的生成、存储和频率限制。后续做营销通知或订单提醒,可以复用同一个服务类,只需新增对应模板。