mews/captcha 验证码源码分析笔记
1

准备使用 mews/captcha 作为注册时的图片验证码。

追了下源码,大致分几步:

  1. 启动app时,注册 captcha 验证规则。这里利用的是 注册自定义验证规则中的 Using Extensions
    vendor/mews/captcha/src/CaptchaServiceProvider.php

    public function boot()
    {
       ...
        // Validator extensions
        $this->app['validator']->extend('captcha', function($attribute, $value, $parameters)
        {
            return captcha_check($value);
        });
    
        ...
    }
  2. 加载验证码页面时,生成验证码图片,同时将验证码值加入session
    vendor/mews/captcha/src/CaptchaController.php

    public function getCaptcha(Captcha $captcha, $config = 'default')
    {
        if (ob_get_contents())
        {
            ob_clean();
        }
        return $captcha->create($config);
    }
  3. 在注册时,会创建一个validator,将刚才注册的自定义rule写入第二参数数组,第三参数为自定义的错误消息。
    app/Http/Controllers/Auth/RegisterController.php

    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' => '请输入正确的验证码',
        ]);
    }
  4. 然后会对此validator进行validate。captcha这个rule就会将request中的captcha的值与session中的captcha值进行比较,而且是使用password_verify这个函数,避免了时序攻击。
    vendor/mews/captcha/src/Captcha.php

    public function check($value)
    {
        if ( ! $this->session->has('captcha'))
        {
            return false;
        }
    
        $key = $this->session->get('captcha.key');
        $sensitive = $this->session->get('captcha.sensitive');
    
        if ( ! $sensitive)
        {
            $value = $this->str->lower($value);
        }
    
        $this->session->remove('captcha');
    
        return $this->hasher->check($value, $key);
    }
  5. 如果出现图片验证码输入错误或者是未输入,则会跳转为上一个页面(也就是注册页面),原因是因为ValidationException是一种比较特殊的异常,不会直接抛出错误,会将异常转换为某种预定义的响应,在这个场景下,就会跳转到上一个页面并附上除了密码的input值并带上错误信息了,这也是验证失败后,可以显示错误信息的原因。
    vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php

    protected function invalid($request, ValidationException $exception)
    {
        $url = $exception->redirectTo ?? url()->previous();
    
        return redirect($url)
                ->withInput($request->except($this->dontFlash))
                ->withErrors(
                    $exception->errors(),
                    $exception->errorBag
                );
    }
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!