mews/captcha 验证码源码分析笔记
准备使用
mews/captcha
作为注册时的图片验证码。
追了下源码,大致分几步:
-
启动
app
时,注册captcha
验证规则。这里利用的是 注册自定义验证规则中的 Using Extensions
vendor/mews/captcha/src/CaptchaServiceProvider.phppublic function boot() { ... // Validator extensions $this->app['validator']->extend('captcha', function($attribute, $value, $parameters) { return captcha_check($value); }); ... }
-
加载验证码页面时,生成验证码图片,同时将验证码值加入
session
。
vendor/mews/captcha/src/CaptchaController.phppublic function getCaptcha(Captcha $captcha, $config = 'default') { if (ob_get_contents()) { ob_clean(); } return $captcha->create($config); }
-
在注册时,会创建一个validator,将刚才注册的自定义rule写入第二参数数组,第三参数为自定义的错误消息。
app/Http/Controllers/Auth/RegisterController.phpprotected 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' => '请输入正确的验证码', ]); }
-
然后会对此validator进行validate。
captcha
这个rule就会将request
中的captcha
的值与session
中的captcha
值进行比较,而且是使用password_verify这个函数,避免了时序攻击。
vendor/mews/captcha/src/Captcha.phppublic 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); }
-
如果出现图片验证码输入错误或者是未输入,则会跳转为上一个页面(也就是注册页面),原因是因为
ValidationException
是一种比较特殊的异常,不会直接抛出错误,会将异常转换为某种预定义的响应,在这个场景下,就会跳转到上一个页面并附上除了密码的input值并带上错误信息了,这也是验证失败后,可以显示错误信息的原因。
vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.phpprotected function invalid($request, ValidationException $exception) { $url = $exception->redirectTo ?? url()->previous(); return redirect($url) ->withInput($request->except($this->dontFlash)) ->withErrors( $exception->errors(), $exception->errorBag ); }
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: