Laravel 5.5 注册登录验证码
发布时间:2018-04-01 编辑:小张个人博客 查看次数:7905
我们的注册功能存在一个问题,因我们表单未添加任何防护,恶意用户可以轻易使用机器人自动化注册新用户。机器人自由注册,对我们站点稳定性来讲是巨大的威胁,恶意用户可以很轻易的通过机器人程序在短时间内,注册大量用户,甚至于填满我们的数据库。
验证码是防止恶意破解密码、刷票、论坛灌水、刷页的手段。验证码有 多种类型。 本项目中我们将使用图片验证码,其原理是让用户输入一个扭曲变形的图片上所显示的文字或数字,扭曲变形是为了避免被光学字符识别软件(OCR)自动辨识。由于计算机无法识别验证码的图片,所以回答出问题的用户就可以被认为是人类。
接下来我们将使用验证码来防卫的用户注册功能。
我们将以 ValidateCode.php 作为基础来实现 Laravel 中的验证码功能。
<?php namespace App\Tool\Validate; //验证码类 class ValidateCode { private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';//随机因子 private $code;//验证码 private $codelen = 4;//验证码长度 private $width = 130;//宽度 private $height = 50;//高度 private $img;//图形资源句柄 private $font;//指定的字体 private $fontsize = 20;//指定字体大小 private $fontcolor;//指定字体颜色 //构造方法初始化 public function __construct() { $this->font = public_path() . '/fonts/Elephant.ttf';//注意字体路径要写对,否则显示不了图片 $this->createCode(); } //生成随机码 private function createCode() { $_len = strlen($this->charset) - 1; for ($i = 0;$i < $this->codelen;++$i) { $this->code .= $this->charset[mt_rand(0, $_len)]; } } //生成背景 private function createBg() { $this->img = imagecreatetruecolor($this->width, $this->height); $color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255)); imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $color); } //生成文字 private function createFont() { $_x = $this->width / $this->codelen; for ($i = 0;$i < $this->codelen;++$i) { $this->fontcolor = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156)); imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(1, 5), $this->height / 1.4, $this->fontcolor, $this->font, $this->code[$i]); } } //生成线条、雪花 private function createLine() { //线条 for ($i = 0;$i < 6;++$i) { $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156)); imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color); } //雪花 for ($i = 0;$i < 100;++$i) { $color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255)); imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color); } } //输出 private function outPut() { header('Content-type:image/png'); imagepng($this->img); imagedestroy($this->img); } //对外生成 public function doimg() { $this->createBg(); $this->createLine(); $this->createFont(); $this->outPut(); } //获取验证码 public function getCode() { return strtolower($this->code); } }
可以看到这些配置选项都非常通俗易懂,$codelen, $width, $height , $fontsize,$fontcolor 分别是定义验证码类型,你可以在此修改对应选项自定义验证码的长度、宽度、高度、字体大小、文字颜色等属性。
新建 ValidateController.php
// 生成验证码 public function create(Request $request) { $validateCode = new ValidateCode; // 验证码保存到SESSION中 $request->session()->put('validate_code', $validateCode->getCode()); return $validateCode->doimg(); } 设置路由 Route::get('captcha', 'Auth\ValidateController@create')->name('create');
前端展示,分为两步:
1、前端展示 —— 生成验证码给用户展示,并收集用户输入的答案;
2、后端验证 —— 接收答案,检测用户输入的验证码是否正确。
接下来我们请将 register.blade.php 文件中找个合适位置添加为以下内容:
<div class="form-group {{ $errors->has('captcha') ? ' has-error' : '' }}"> <label for="captcha" class="col-md-4 control-label">Captcha</label> <div class="col-md-6"> <input id="captcha" class="form-control" name="captcha" > <img class="thumbnail captcha" src="{{ url('captcha') }}" onclick="this.src='{{ url('captcha') }}'+'?'+Math.random()" title="点击图片重新获取验证码"> @if ($errors->has('captcha')) <span class="help-block"> <strong>{{$errors->first('captcha') }}</strong> </span> @endif </div> </div>
后端验证( RedirectsUsers.php )
前端展示部分我们已经开发完毕,接下来处理后端验证逻辑。ValidateCode.php 能很好的兼容 Laravel 5.5
public function register(Request $request){ $data = Input::all(); $rules = [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', 'captcha' => 'required', ]; $message = [ 'captcha.required' => '验证码不能为空', ]; // 验证数据 $validator = Validator::make($data,$rules,$message); if($validator -> passes()){ if($data['captcha'] != session('validate_code')){ $validator->errors()->add('captcha', '请输入正确的验证码!'); // 添加错误提示信息 return back() -> withErrors($validator); } event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect($this->redirectPath()); }else{ return back() -> withErrors($validator); } }
以下内容对上述代码的一个说明:
验证规则
如果传入的请求参数未通过给定的验证规则呢?正如前面所提到的,Laravel 会自动把用户重定向到先前的位置。
另外,所有的验证错误信息会被自动 闪存至 session 。
我们不必在 GET 路由中将错误消息显式绑定到视图。因为 Lavarel 会检查在 Session 数据中的错误信息,并自动将其绑定到视图(如果存在)。
而其中的变量 $errors 是 Illuminate\Support\MessageBag 的一个实例。要获取关于这个对象的更多信息
$rules = [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', 'captcha' => 'required', ];
自定义错误消息
如果有需要的话,你也可以自定义错误消息取代默认值进行验证。有几种方法可以指定自定义消息。
首先,你可以将自定义消息作为第三个参数传递给 Validator::make 方法:
$message = [ 'captcha.required' => '验证码不能为空', ];
处理错误消息
在 Validator 实例上调用 errors 方法后,会得到一个 Illuminate\Support\MessageBag 实例,
该实例具有各种方便的处理错误消息的方法。$errors 变量是自动提供给所有视图的 MessageBag 类的一个实例。
// 验证数据 $validator = Validator::make($data,$rules,$message); if($validator -> passes()){ if($data['captcha'] != session('validate_code')){ $validator->errors()->add('captcha', '请输入正确的验证码!'); // 添加错误提示信息 return back() -> withErrors($validator); } event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect($this->redirectPath()); }else{ return back() -> withErrors($validator); }
接下来继续测试:
查看所有字段的错误消息
如果你想要得到所有字段的错误消息,可以使用 all 方法:
foreach ($errors->all() as $message) { // }
查看特定字段的第一个错误消息
如果要查看特定字段的第一个错误消息,可以使用 first 方法:
$errors = $validator->errors(); echo $errors->first('email');
Copyright © 小张个人博客 All Rights Reserved 渝ICP备15006773号-1
联系方式:1042563239@qq.com | 本站文章仅供学习和参考