邮件验证逻辑
$token = Str::random(16);
Cache::set('email_verification_' . $notifiable->email, $token, 30);
$url = $urlString . '?email_verification_token=' . $token;
邮箱包含此链接。点击此链接发出get请求去完成校验。
1. 数据库检查验证字段是不是已经验证过了。
2. email token 是不是已经过期。
3. 是不是验证通过。
验证Cache::get('email_verification_' . $notifiable->email) === $request->email_verification_token
图片与手机验证的逻辑
通常情况下的流程
手机号输入和图片验证输入在同一个界面。验证图片&&手机号,然后发送短信,验证短信。
每个初始化form有一个随机的token,session记录初始化captcha_code。
//表单初始化页面
// when loading, render token in form.
session_start();
$render_token = md5(random(15));
$_SESSION['captcha'][$render_token] = $captchaAPI->getPhrase();
//请求校验函数
// when submit
// avoid repeat submit
if ($_SESSION['token'] === $request->render_token) {
throw new Exception('Can\'t submit twice');
}
session_start();
if (!$_SESSION['token']) {
$_SESSION['token'] = $request->render_token;
}
if ($_SESSION['captcha'][$request->render_token] === $request->captcha_code && available($phone)) {
unset($_SESSION['captcha']);
unset($_SESSION['token']);
// 生成手机code保存到cache,发送手机短信, 进行短信验证码验证
}
提交之后request token get code与此request code比较?
分步验证流程:
- 填写手机号,提交。获得图片验证码的图片,并且cache存了captcha_code。return captcha_key。
- 填写图片验证码,提交。request 提交输入的code和captcha_key,通过captcha_key获取captcha_code然后和code比较。成功的话发送短信,并在cache中用phone_cache_token保存短信验证码phone_code, return phone_cache_token;
- 填写手机收到的短信码,通过phone_cache_token获得phone_code与提交的code比较,成功则登录。
图片验证逻辑
生成图片验证码,需要以手机号作为参数
Web 版本 https://github.com/mewebstudio/captcha
API 版本 https://github.com/Gregwar/Captcha
//调用之前正则检查国内的手机号
// /^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/
$key='captcha_' . random(15);
\Cache::put($key, ['phone' => $request->phone, 'captcha_code' => $captchaAPI->getPhrase()], $expiredAt);
return $res[
'captcha_key' => $key,
'captcha_image_content' => $captchaAPI->inline()
];
校验:
$imageCache = \Cache::get($requestResponse['captcha_key']);
$request->captcha_code == $imageCache['captcha_code'];
短信验证逻辑
在图片验证码验证成功之后,进行短信验证
// 生成4位随机数,左侧补0, cache 保存
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);
$phone_cache_token = 'verificationCode_' . str_random(15);
$expiredAt = now()->addMinutes(10);
\Cache::put($phone_cache_token, ['code' => $code], $expiredAt);
// 调用手机短信API,把code发到手机
try {
$result = $easySms->send($phone, [
'content' => "【Lbbs社区】您的验证码是{$code}。如非 本人操作,请忽略本短信"
]);
} catch (\Exception $e) {
log('logfile.log', $e->getMessage());
}
return $res['verification_key' => $phone_cache_token, 'phone' => $phone];
$verifyData = \Cache::get($res['verification_key']);
校验:
//防止时序攻击的字符串比较
hash_equals($verifyData['code'], $request->verification_code)
Q:
提供API的服务商把cache存在本机上,如果访问量大的话,本机的cache文件会很大吗?
网友评论