🌦️开封小雨7~17℃北京 12/4℃上海 20/11℃广州 26/19℃深圳 25/18℃杭州 22/11℃成都 21/11℃全国天气 »登录
让上网更简单

laravel中验证码及图片上传

来源 源码时代官网 发布 2019-10-09 阅读 8 次 字数 5478
2019/10/09 17:27 分类: 技术交流 浏览:1 我们的注册功能存在一个问题,因我们表单未添加任何防护,恶意用户可以轻易使用机器人自动化注册新用户。机器人自由注册,对我们站点稳定性来讲是巨大的威胁,恶意用户可以很轻易的通过机器人程序在短时间内,注册大量用户,甚至于填满我们的数据库。 验证码 是防止恶意破解密码、刷票、论坛灌水、刷页的手段。验证码有 多种类型。 本项目中我们将使用图片验证码,其原理是让用户输入一个扭曲变形的图片上所显示的文字或数字,扭曲变形是为了避免被光学字符识别软件(OCR)自动辨识。由于计算机无法识别验证码的图片,所以回答出问题的用户就可以被认为是人类。 接下来我们将使用验证码来防卫的用户注册功能。 我们将以第三方扩展包 mews/captcha 作为基础来实现 Laravel 中的验证码功能。 使用 Composer 安装:(需要打开fileinfo扩展) composer require "mews/captcha:~2.0" 修改config/app.php,在providers添加 Mews\Captcha\CaptchaServiceProvider::class, 'providers' => [ 在aliases添加 'Captcha' => Mews\Captcha\Facades\Captcha::class, 'aliases' => [ 运行以下命令生成配置文件 config/captcha.php: php artisan vendor:publish 我们可以打开配置文件,查看其内容: config/captcha.php return [ 'characters' => '2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ', 'default' => [ 'length' => 5, 'width' => 120, 'height' => 36, 'quality' => 90, 'flat' => [ 'length' => 6, 'width' => 160, 'height' => 46, 'lines' => 6, 'bgImage' => false, 'bgColor' => '#ecf2f4', 'fontColors'=> ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f', '#f57c00', '#795548'], 'contrast' => -5, 'mini' => [ 'length' => 3, 'width' => 60, 'height' => 32, 'inverse' => [ 'sensitive' => true, 'angle' => 12, 'sharpen' => 10, 'blur' => 2, 'invert' => true, 可以看到这些配置选项都非常通俗易懂,characters 选项是用来显示给用户的所有字符串,default, flat, mini, inverse 分别是定义的四种验证码类型,你可以在此修改对应选项自定义验证码的长度、背景颜色、文字颜色等属性,在此不做过多叙述。 此扩展包的使用分为两步: 前端展示 —— 生成验证码给用户展示,并收集用户输入的答案; 后端验证 —— 接收答案,检测用户输入的验证码是否正确。 captcha_src() 方法是 mews/captcha 提供的辅助方法,用于生成验证码图片链接; 『验证码』区块中 onclick() 是 JavaScript 代码,实现了点击图片重新获取验证码的功能,允许用户在验证码太难识别的情况下换一张图片试试。 前端展示部分我们已经开发完毕,接下来处理后端验证逻辑。 mews/captcha 是专门为 Laravel 量身定制的扩展包,能很好的兼容 Laravel 生成的注册逻辑。我们只需要在注册的时候,添加上表单验证规则即可: app/Http/Controllers/Auth/RegisterController.php class RegisterController extends Controller * Get a validator for an incoming registration request. * @param array $data * @return \Illuminate\Contracts\Validation\Validator protected function validator(array $data) return Validator::make($data, [ 'name' => 'required|string|max:255', 'captcha' => 'required|captcha', 'captcha.required' => '验证码不能为空', 'captcha.captcha' => '请输入正确的验证码', 我们添加了验证规则: 表达式里的第二个 captcha 是 mews/captcha 自定义的表单验证规则。扩展包非常巧妙地利用了 Laravel 表单验证器提供的 自定义表单验证规则 功能。令我们在开发验证码时非常方便。 Validator 表单验证的 make() 方法第三个参数是自定义错误提示,这里我们对验证码的错误提示进行自定义。 给数据表添加相应的字段 接下来我们将开发个人资料里的头像上传功能。 首先我们需在 User 模型里将 avatar 字段加入到允许修改的白名单 $fillable 中: 接下来我们在 资料编辑页面 的『个人简介』编辑框下面,增加头像上传的选项: resources/views/users/edit.blade.php.
个人简介 {{ old('introduction', $user->introduction ) }} 用户头像 @if($user->avatar) avatar }}" width="200" /> 在 Laravel 中,我们可直接通过 请求对象(Request) 来获取用户上传的文件,如以下两种方法: // 第一种方法 $file = $request->file('avatar'); // 第二种方法,可读性更高 $file = $request->avatar; 接下来我们将在 UsersController 的 update() 方法中,利用 Laravel 的 dd() 调试方法,来查看文件上传的情况: app/Http/Controllers/UsersController.php class UsersController extends Controller public function update(UserRequest $request, User $user) dd($request->avatar); $user->update($request->all()); return redirect()->route('users.show', $user->id)->with('success', '个人资料更新成功!'); 访问 资料编辑页面 ; 点击 『choose file』 按钮,选择图片; 点击『保存』按钮提交表单: 打印的结果居然为空。 经过一番仔细检查后,发现是因为我们忘记为表单添加 enctype="multipart/form-data" 声明了。请记住,在图片或者文件上传时,为表单添加此句声明是必须的。那我们再次修改下: resources/views/users/edit.blade.php id) }}" method="POST" accept-charset="UTF-8" enctype="multipart/form-data"> Laravel 的『用户上传文件对象』底层使用了 Symfony 框架的 UploadedFile 对象进行渲染,为我们提供了便捷的文件读取和管理接口,我们将在后面使用这些方法。 现在我们已经能得到用户上传的图片数据了,接下来是对图片进行存储。 存储用户上传图片 $fileName = $request->file('cover')->store('public/cover'); //获取文件路径 var_dump(Storage::url($fileName)); 由于图片是保存在storage目录,浏览器无法直接访问,所有需要 使用 Artisan 命令 storage:link 来创建符号链接: php artisan storage:link 本项目中,我们不止上传头像需要用到『图片上传功能』,在后面其他功能中,我们也将会允许用户上传图片,所以此处我们需要预先设计一下图片上传相关的逻辑,我们可以将『图片上传』核心操作做成一个工具类: app/Handlers/ImageUploadHandler.php namespace App\Handlers; class ImageUploadHandler // 只允许以下后缀名的图片文件上传 protected $allowed_ext = ["png", "jpg", "gif", 'jpeg']; public function save($file, $folder, $file_prefix) // 构建存储的文件夹规则,值如:uploads/images/avatars/201709/21/ // 文件夹切割能让查找效率更高。 $folder_name = "uploads/images/$folder/" . date("Ym/d/", time()); // 文件具体存储的物理路径,`public_path()` 获取的是 `public` 文件夹的物理路径。 // 值如:/home/vagrant/Code/larabbs/public/uploads/images/avatars/201709/21/ $upload_path = public_path() . '/' . $folder_name; // 获取文件的后缀名,因图片从剪贴板里黏贴时后缀名为空,所以此处确保后缀一直存在 $extension = strtolower($file->getClientOriginalExtension()) ?: 'png'; // 拼接文件名,加前缀是为了增加辨析度,前缀可以是相关数据模型的 ID // 值如:1_1493521050_7BVc9v9ujP.png $filename = $file_prefix . '_' . time() . '_' . str_random(10) . '.' . $extension; // 如果上传的不是图片将终止操作 if ( ! in_array($extension, $this->allowed_ext)) { return false; // 将图片移动到我们的目标存储路径中 $file->move($upload_path, $filename); 'path' => config('app.url') . "/$folder_name$filename" 我们将使用 app/Handlers 文件夹来存放本项目的工具类,『工具类(utility class)』是指一些跟业务逻辑相关性不强的类,Handlers 意为 处理器 ,ImageUploadHandler 意为图片上传处理器,简单易懂。 接下来我们需要在 UsersController 里调用: use App\Handlers\ImageUploadHandler; public function update(UserRequest $request, ImageUploadHandler $uploader, User $user) $data = $request->all(); if ($request->avatar) { $result = $uploader->save($request->avatar, 'avatars', $user->id); if ($result) { $data['avatar'] = $result['path']; $user->update($data); 因为我们使用了命名空间,所以需要在顶部加载 use App\Handlers\ImageUploadHandler;; $data = $request->all(); 赋值 $data 变量,以便对更新数据的操作; 以下代码处理了图片上传的逻辑,注意 if ($result) 的判断是因为 ImageUploadHandler 对文件后缀名做了限定,不允许的情况下将返回 false: $user->update($data); 这一步才是执行更新。

当前文章地址:http://nicefinish.cn/quick/wire/57186

↑