04 短信验证码
安全173 字
■ 验证码生成/验证码限制/安全提示/凭证校验
场景:用户注册、密码重置、密码找回时。
说明:复杂度至少6位数字或字母,一次一用,建议有效期不超过180秒。前后端设置用户获取频率为60秒一次,建议每个用户每天获取的短信最多10条。增加安全提示:至少含本次操作的功能、验证码发送编号、是否是个人自己操作的风险等信息。禁止在响应中返回验证码,服务器端同时校验密码、短信验证码等凭证信息,防止出现多阶段认证绕过的漏洞。
<?php
function sendCode($phone) {
session_start();
$time = time();
if ($_SESSION[static::MESSAGE_CODE_USER] && $_SESSION[static::MESSAGE_CODE_TIME] + 60 > $time) {
echo "Error: send sms code too frequeue, try it later.";
return -1;
}
if (!isset($_SESSION[static::SESSION_MESSAGE_CODE_COUNT])) {
$_SESSION[static::SESSION_MESSAGE_CODE_COUNT] = 1;
} else {
$_SESSION[static::SESSION_MESSAGE_CODE_COUNT]++;
}
if ($_SESSION[static::SESSION_MESSAGE_CODE_COUNT] >= 5) {
$this->unsetCode();
echo "sms code send time more than five, try it later...";
return -1;
}
setcookie(session_name(), session_id(), $time+60,"/");
$phone = $_GET["phone"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://apis.xxx.com/sms/send?mobile={$phone}&key={$key}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$json = curl_exec($ch);
$rets = json_decode($json, true);
$_SESSION[static::MESSAGE_CODE_USER] = $phone;
$_SESSION[static::MESSAGE_CODE] = $rets['smscode'];
$_SESSION[static::MESSAGE_CODE_TIME] = $time;
echo $rets['error_code'];
return 0;
}
function checkCode($code, $phone) {
session_start();
if (!isset($_SESSION[static::MESSAGE_CODE_TIME]) || !isset($_SESSION[static::MESSAGE_CODE])) {
echo "Error: sms code is null.";
return -1;
}
if ($_SESSION[static::MESSAGE_CODE_TIME] + 60*3 < time()) {
$this->unsetCode();
echo "Error: sms code is timeout.";
return -1;
}
if ($_SESSION[static::MESSAGE_CODE] == $code && $_SESSION[static::MESSAGE_CODE_USER] == $phone) {
$this->unsetCode();
echo "OK, check sms code success.";
return 0;
}
echo "Error, check sms code fail.";
return -1;
}
?>