Laravel - 验证码

验证码

验证码 是防止恶意破解密码、刷票、论坛灌水、刷页的手段。验证码有 多种类型。 本项目中我们将使用图片验证码,其原理是让用户输入一个扭曲变形的图片上所显示的文字或数字,扭曲变形是为了避免被光学字符识别软件(OCR)自动辨识。由于计算机无法识别验证码的图片,所以回答出问题的用户就可以被认为是人类。

接下来我们将使用验证码来防卫的用户注册功能。

安装扩展包

我们将以第三方扩展包 mews/captcha 作为基础来实现 Laravel 中的验证码功能。

使用 Composer 安装:

$ composer require "mews/captcha:~2.0"

运行以下命令生成配置文件 config/captcha.php:

$  php artisan vendor:publish --provider='Mews\Captcha\CaptchaServiceProvider' 

我们可以打开配置文件,查看其内容:

config/captcha.php

<?php

return [

    'characters' => '2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ',

    'default'   => [
        'length'    => 5,
        'width'     => 120,
        'height'    => 36,
        'quality'   => 90,
    ],

    'flat'   => [
        'length'    => 6,
        'width'     => 160,
        'height'    => 46,
        'quality'   => 90,
        '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'   => [
        'length'    => 5,
        'width'     => 120,
        'height'    => 36,
        'quality'   => 90,
        'sensitive' => true,
        'angle'     => 12,
        'sharpen'   => 10,
        'blur'      => 2,
        'invert'    => true,
        'contrast'  => -5,
    ]

];

可以看到这些配置选项都非常通俗易懂,characters 选项是用来显示给用户的所有字符串,default, flat, mini, inverse 分别是定义的四种验证码类型,你可以在此修改对应选项自定义验证码的长度、背景颜色、文字颜色等属性,在此不做过多叙述。

页面嵌入

此扩展包的使用分为两步:

  1. 前端展示 —— 生成验证码给用户展示,并收集用户输入的答案;
  2. 后端验证 —— 接收答案,检测用户输入的验证码是否正确。

1. 前端展示

接下来我们请将注册页面模板 register.blade.php 内容替换为以下:

resources/views/auth/register.blade.php

<div class="form-group row">
  <label for="captcha" class="col-md-4 col-form-label text-md-right">验证码</label>

  <div class="col-md-6">
    <input id="captcha" class="form-control{{ $errors->has('captcha') ? ' is-invalid' : '' }}" name="captcha" required>

    <img class="thumbnail captcha mt-3 mb-2" src="{{ captcha_src('flat') }}" onclick="this.src='/captcha/flat?'+Math.random()" title="点击图片重新获取验证码">

    @if ($errors->has('captcha'))
      <span class="invalid-feedback" role="alert">
        <strong>{{ $errors->first('captcha') }}</strong>
      </span>
    @endif
  </div>
</div>

代码讲解:

  1. 我们首先将此文件里的英文翻译为中文;
  2. 在『确认密码』区块代码下,我们增加了『验证码』区块代码;
  3. captcha_src() 方法是 mews/captcha 提供的辅助方法,用于生成验证码图片链接;
  4. 『验证码』区块中 onclick() 是 JavaScript 代码,实现了点击图片重新获取验证码的功能,允许用户在验证码太难识别的情况下换一张图片试试。

因涉及到样式代码编译,请确保虚拟机里的 $ npm run watch-poll 命令处于运行中。

2. 后端验证

mews/captcha 是专门为 Laravel 量身定制的扩展包,能很好的兼容 Laravel 生成的注册逻辑。我们只需要在注册的时候,添加上表单验证规则即可:

app/Http/Controllers/Auth/RegisterController.php

<?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'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:6', 'confirmed'],
            'captcha' => ['required', 'captcha'],
        ], [
            'captcha.required' => '验证码不能为空',
            'captcha.captcha' => '请输入正确的验证码',
        ]);
    }
    .
    .
    .
}

我们添加了验证规则:

'captcha' => ['required', 'captcha'],

表达式里的第二个 captchamews/captcha 自定义的表单验证规则。扩展包非常巧妙地利用了 Laravel 表单验证器提供的 自定义表单验证规则 功能。令我们在开发验证码时非常方便。

Validator 表单验证的 make() 方法第三个参数是自定义错误提示,这里我们对验证码的错误提示进行自定义。

本作品采用《CC 协议》,转载必须注明作者和本文链接
老哥以后是要做 CTO 的人,这些技术怎么能不会呢?
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3
恶龙咆哮,啊呜!

执行了没反应

2年前 评论

@恶龙咆哮,啊呜! 转 JAVA 了,当时我测过是可以的,你再好好看下。

2年前 评论

@GuanJie 做的不够好,太难受了 1.图片大小无法人工指定,就这一点导致看不清楚 2.api的缓存没检测,没保存住key也不提示!

6个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!