写在前面 paperen这里使用的dcat-admin版本小于2.0,故不能直接使用dcat-login-captcha这个第三包实现 对于2.0以上建议直接用guanguans/dcat-login-captcha

dcat-login-captcha - dcat admin 登录验证码扩展

由于工作原因需要给dcat-admin登录页面增加一个验证码,一开始百度找了一些解决方案

https://paperen.com/file/216

记在dcat-admin中,登陆页面加验证码操作 Laravel - 验证码

两个参考资料paperen都试了一下,最终基本按第一个方案实现出来,但其中踩过一些坑(花了有4、5个小时才弄出来)所以借此机会记录一下 PS:这个真的是保姆级教程

大致思路

  • 通过路由重写原本的登录页面与登录验证入口——修改routes.php、完善AuthController
  • 增加一个生成验证码的接口——需要给这个接口开放权限验证
  • 验证码保存在session中,登录判断增加验证码对比 下面是具体过程

安装gregwar/captcha

composer require gregwar/captcha

重写路由

修改routes.php增加

https://paperen.com/file/217

// 验证码
$router->get('auth/captcha', 'AuthController@captcha');
$router->get('auth/login', 'AuthController@getLogin');
$router->post('auth/login', 'AuthController@postLogin');

对于AuthController的代码,直接在将vendor/dcat/laravel-admin/src/Controllers/AuthController.php打开cv大法一下 对于login的视图文件一样手法,在vendor/dcat/laravel-admin/resources/views/pages/login.blade.php

将AuthController.php开头的view变量按自己路径改下,此处paperen改为,视图则指向在resource目录的views中resources/views/login.blade.php

protected $view = 'login';

登录视图增加验证码,在密码fieldset标签结束后插入以下代码

 
<input id="captcha" type="text" class="form-control {{ $errors->has('captcha') ? 'is-invalid' : '' }}" name="captcha" placeholder="验证码" required autocomplete="current-password" >
@if($errors->has('captcha')) @foreach($errors->get('captcha') as $message) {{$message}}
@endforeach
@endif

拉到最底,有一个表单提交提交事件,这里也稍微调整一下一旦密码或用户名、验证码错误时就重刷一下验证码,代码如下,主要是$('#captcha_img').attr('src', '{{admin_url('auth/captcha')}}'+'?'+Math.random());

 Dcat.ready(function () {
  // ajax表单提交
  $('#login-form').form({
   validate: true,
   success: function (data) {
    if (! data.status) {
     Dcat.error(data.message);
     $('#captcha_img').attr('src', '{{admin_url('auth/captcha')}}'+'?'+Math.random());
     return false;
    }

    Dcat.success(data.message);

    location.href = data.redirect;

    return false;
   }
  });
 });

增加一个生成验证码的接口

接上面路由中的一条$router->get('auth/captcha', 'AuthController@captcha');,这里获取验证码的接口也是指向到AuthController这个控制器中的captcha方法

 public function captcha() {
        $phrase = new PhraseBuilder();
        $code = $phrase->build(4);
        $builder = new CaptchaBuilder($code, $phrase);
        $builder->setBackgroundColor(220, 210, 230);
        $builder->setMaxAngle(25);
        $builder->setMaxBehindLines(0);
        $builder->setMaxFrontLines(0);
        $builder->build(300, 80);
        $phrase = $builder->getPhrase();
        Session::put('code', $phrase);
        Session::save();
        $builder->output();
    }

到这里访问后台已经会看到验证码输入框已经出来但是验证码图片是裂的

https://paperen.com/file/218

auth/captcha接口标记不需要权限验证列表中,打开config/admin.php,定位到auth的except地方,增加上auth/captcha

'except' => [
 'auth/login',
 'auth/logout',
 'auth/captcha',
],

postLogin增加判断验证码正确与否

回到AuthController.php定位到postLogin方法,增加判断验证码逻辑

public function postLogin(Request $request)
{
 $credentials = $request->only([$this->username(), 'password']);
 $remember = (bool) $request->input('remember', false);

 $captcha = $request->input('captcha', null);
 /** @var IlluminateValidationValidator $validator */
 $validator = Validator::make($credentials, [
  $this->username()   => 'required',
  'password'          => 'required'
 ]);

 if (strcasecmp(Session::get('code'), $captcha) !== 0) {
  return $this->error('验证码错误');
 }
 Session::remove('code');
 if ($validator->fails()) {
  return $this->validationErrorsResponse($validator);
 }

 if ($this->guard()->attempt($credentials, $remember)) {
  return $this->sendLoginResponse($request);
 }

 return $this->validationErrorsResponse([
  $this->username() => $this->getFailedLoginMessage(),
 ]);
}

到此登录验证码的功能就ok了

以下为一些可能会遇到的问题以及解决方案

  • 若一直验证码提示不正确,那需要确认session是否有开启了(app/Http/Kernel.php),web中间件组
AppHttpMiddlewareEncryptCookies::class,
IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateViewMiddlewareShareErrorsFromSession::class,
  • 若配置都没问题,那么尝试下手动打印出session的值 https://paperen.com/file/219

请确保生成验证码的接口跟登录验证是在同一个路由组中,如果不是在同一个路由组的话可能会出现在登录验证中拿不到session中的验证码 https://paperen.com/file/220