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 的人,这些技术怎么能不会呢?
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 3
恶龙咆哮,啊呜!

执行了没反应

3年前 评论

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

3年前 评论

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

2年前 评论

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