Laravel结合Redis发送邮箱验证码

Laravel结合Redis发
摘要:每天进步一点点... 我们在某些业务上,需要注册邮箱,为避免邮箱注册混乱、乱用他人邮箱,这就需要对邮箱进行验证。 一、设计思路 1、用户输入邮箱,点击验证 2、后端接收到邮箱后,随机生成一个code,用邮箱作为key,code为值保存到redis中,并使用laravel封装的Mail类发送给用户 3、用户收到邮件后,获取验证码并输入,后端把email、code和redis保存的值做一个匹对 二、前期准备 1、修改.env配置文件里面email部分的内容 MAIL_MAILER=smtp MAIL_HOST=smtp.qq.com MAIL_PORT=465 MAIL_USERNAME=xxxx@qq.com MAIL_PASSWORD=xxxxxxxxxxxxxxxxx MAIL_ENCRYPTION=ssl MAIL_FROM_ADDRESS=xxxx@qq.com MAIL_FROM_NAME=糊涂 2、使用命令创建`EmailVerifyController.php`控制器 ``` php artisan make:controller Index/EmailVerifyController ``` 3、在routes/web.php中注册相关路由 ```php <?php use Illuminate\Support\Facades\Route; Route::get("sendEmailCode", "Index\EmailVerifyController@sendEmailCode"); Route::get("verify", "Index\EmailVerifyController@verify"); ``` 4、在resoures/views/mail创建`SendEmailCode.blade.php`模块文件 三、实现代码 1、EmailVerifyController.php控制器 ```php <?php namespace App\Http\Controllers\Index; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Mail\Message; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Redis; class EmailVerifyController extends Controller { /** * 发送邮箱验证码 * @param Request $request * @return array */ public function sendEmailCode(Request $request) { $email = $request->input("email"); $code = rand(100000, 999999);//验证码 $expireTime = 60 * 3;//过期时间 $EMAIL_VERIFY_CODE = "email:verify:code:" . $email;//redis key Redis::setex($EMAIL_VERIFY_CODE, $expireTime, $code); Mail::send("mail.SendEmailCode", ["code" => $code, "email" => $email], function (Message $message) use ($email) { $message->to($email); $message->subject("糊涂个人博客——邮箱验证"); }); if (Mail::failures()) { return ["code" => 0, "msg" => "warning"]; } return ["code" => 1, "msg" => "success"]; } /** * 验证 * @param Request $request * @return array */ public function verify(Request $request) { $email = $request->input("email"); $code = $request->input("code"); $EMAIL_VERIFY_CODE = "email:verify:code:" . $email;//redis key $isCode = Redis::get($EMAIL_VERIFY_CODE); if ($isCode && $isCode === $code) { return ["code" => 1, "msg" => "success"]; } return ["code" => 0, "msg" => "warning"]; } } ``` 2、SendEmailCode.blade.php模块 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> app { line-height: 150%; } </style> </head> <body> <div id="app"> <div>亲爱的用户:</div> <br/> <div>您好!</div> <br/> <div>感谢您使用糊涂个人博客开发平台。您正在进行邮箱验证,请在验证码输入框中输入此次验证码<span style="color: red">{{$code}}</span>(3分钟内有效)以完成验证。</div> <div>如非本人操作,请忽略此邮件,由此给您带来的不便请谅解!</div> <br/> <div>糊涂个人博客开发平台</div> </div> </body> </html> ``` 四、实现效果 自己可以根据相关需要修改样式代码 ![QQ截图20210129223551.jpg](https://api.lpya.cn/HtBlog/public/upload/article/20210129/07a8c8e23f2bfc8f6ddeb27608ae831e.jpg)

Laravel结合Redis实现黑名单、倒计时、防刷功能

Laravel结合Redis实
摘要:每天进步一点点... 新建的博客,我们如何限制别人恶意攻击、频繁请求接口,导致数据库崩溃?我们可以使用Redis对请求的IP做一个简单的限制。 一、设计思路 1、Redis中使用有序set表存放黑名单列表、频繁请求列表。 2、用户访问,设置一个锁,数值为1,过期时间10秒。 3、用户每次请求接口1次,锁的数值加1。在10秒内接口访问次数超过20次,则把该用户IP或uid添加到频繁请求列表中,score的值为当前时间,数据库表频繁请求次加1。 4、若频繁请求次数超过设定次数,则添加到redis黑名单列表中。 二、前期准备 1、创建RedisKey.php ```php <?php namespace App\Http\Common; class RedisKey { public static $USER_BLACK_LIST = "user:black:list";//黑名单列表 public static $USER_FREQUENT_REQUEST_LIST = "user:frequent:request:list";//频繁请求列表 public static $USER_FREQUENT_REQUEST_LOCK = "user:frequent:request:lock";//锁 } ``` 2、创建数据库表 ![微信截图_20210107224919.png](https://api.lpya.cn/HtBlog/public/upload/article/20210107/f8470485b3609d9b4c65840131a9295b.png) 3、使用命令创建CheckRequest.php路由中间件 ``` php artisan make:middleware CheckRequest ``` 三、实现代码 ```php <?php namespace App\Http\Middleware; use App\Http\Common\Code; use App\Http\Common\RedisKey; use App\Models\FrontUser; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Redis; class CheckRequest { /** * Handle an incoming request. * * @param Request $request * @param Closure $next * @return mixed */ public function handle($request, Closure $next) { $ip = request()->ip(); //查看redis黑名单中是否存在该IP $isBlack = Redis::zscore(RedisKey::$USER_BLACK_LIST, $ip); if ($isBlack) { return ["code" => Code::$USER_BLACK, "msg" => "由于您近期异常请求过于频繁,已限制访问。如需取消限制,请联系管理员:邮箱1048672466@qq.com!"]; } $user = new FrontUser(); $isUser = $user->where(["ip" => $ip])->first(); //数据库中已设置为黑名单或频繁请求数大于等于10 if ($isUser) { //查看数据库表中频繁请求次数是否超过10次,是就把该用户列入黑名单并修改相关字段 if ($isUser->black_list === 1 || $isUser->frequent_num >= 10) { $isUser->black_list = 1; $isUser->save(); Redis::zadd(RedisKey::$USER_BLACK_LIST, 1, $isUser->ip); return ["code" => Code::$USER_BLACK, "msg" => "由于您近期异常请求过于频繁,已限制访问。如需取消限制,请联系管理员:邮箱1048672466@qq.com!"]; } } $time = 5;//锁过期时间 $limit = 20;//5秒内请求次数,超过就触发防刷机制 $lock_time = 60;//每次防刷的锁60秒 //redis频繁请求列表 $start_time = Redis::zscore(RedisKey::$USER_FREQUENT_REQUEST_LIST, $ip); //如果redis频繁请求列表中存在该用户IP,且间隔当前时间少于60秒 if (time() - $start_time < $lock_time) { //返回剩余时间 return response(["code" => Code::$USER_FREQUENT, "msg" => "频繁请求!", "data" => $lock_time - (time() - $start_time)]); } $frequentLock = RedisKey::$USER_FREQUENT_REQUEST_LOCK . ":" . $ip; $isFrequent = Redis::get($frequentLock); if (!$isFrequent) { Redis::setex($frequentLock, $time, 1); //设置锁 return $next($request); } Redis::incr($frequentLock);//锁过期时间类数值自增 //设定时间内请求次数大于设定次数,触发防刷机制 if ($isFrequent > $limit) { Redis::zadd(RedisKey::$USER_FREQUENT_REQUEST_LIST, time(), $ip); Redis::expire(RedisKey::$USER_FREQUENT_REQUEST_LIST, 60 * 5); $isUser->increment("frequent_num"); $isUser->save(); } return $next($request); } } ```
网站信息
博主: 糊涂
Github: Github
联系邮箱:1048672466@qq.com
在线人数: 0
文章数量: 10
访问总量: 3560