captcha icon indicating copy to clipboard operation
captcha copied to clipboard

Captcha validation issue on Ajax Calls

Open khalilst opened this issue 7 years ago • 16 comments

Captcha validation works fine in simple form submit but it always returns false in ajax calls. I did remove the captcha from session as some poeple suggested, but it has no effect. This is my js code:

        var data = {
            _token: token,
            email: form.find('[name="email"]').val(),
            captcha: form.find('[name="captcha"]').val()
        }
        $.post(url, data, function(data) {
            if (data.result == 'OK') {
                form.find('.alert').fadeIn(250);
                red.fadeOut(250);
                setTimeOut(function() {
                    form.closest('popover').fadeOut(500);
                }, 1000);
            } else {
                red.html(data.message).fadeIn(500);
            }
        })

And this is my Laravel code:

    Session::forget('captcha');
    $v = Validator::make(Input::all(), [
        'captcha' => 'required|captcha',
        'email' => 'required|email',
    ]);

I missed something?!

khalilst avatar Aug 30 '17 07:08 khalilst

I found the problem, also other people mentioned it before. First removing the captcha from session is completely worng. Second in the source code after every validation the the captcha goes removed from the session, it's 50% wrong :), because we will need it after validation fails, but it's removed.

So as a temporary solution I suggest store the session before validation and reload only after validation fails. But the permanent solution is correcting the source code by our respected friends @mewebstudio .

Temporary Code could be like this:

        $captcha = Session::get('captcha');
        if (Validator::make(Input::only('captcha'), ['captcha' => 'required|captcha'])->fails()) {
            Session::put('captcha', $captcha);
        }

khalilst avatar Aug 30 '17 08:08 khalilst

我也发现了这个问题,在ajax异步验证的时候只会response false 如果是在form submit提交,http Request请求,使用$this->validate()验证,captcha规则是可行的, 但是如果发起一个ajax request验证,使用Validator::make()->validate()的方法,captcha规则不起作用. 另外,我发现似乎ajax的每一次post提交请求,都会对captcha造成影响,如果使用复制粘贴的方法,一次性在验证码的输入框粘贴完整,正确的验证码,ajax的验证结果是正确的,但是在submit提交的时候会失败,这应该和Validator::make()中的captcha有关,因为如果我在验证规则里把captcha的验证规则取消,就可以正常提交表单. I also discovered the problem of response false only when AJAX is asynchronously validated The captcha rule is feasible while a form submit is submitted, the HTTP Request request is used, and $this->validate () is used to validate it, However, if you launch a Ajax request validation, use the Validator:: make () ->validate () method, and the captcha rule didn't work. In addition, I found that every post submission request for Ajax would have an impact on captcha. If you use copy and paste method, once in the verification code input box to paste the complete, correct verification code, AJAX verification result is correct, but the submit submission callback will fail, it should be Validator:: make (captcha) in, because if I cancel the validation rule of the Captcha, the form can be submitted properly

shanhai3000 avatar Sep 03 '17 17:09 shanhai3000

我找到了原因并且找到了解决的办法 使用ajax post异步验证会出现false的原因是,在输入captcha之后进行post提交的一瞬间(例如绑定了失去焦点post事件),源代码执行了清除session的动作,源代码是: $this->session->remove('captcha') 这样的话,在点击进行表单提交时,session中已经没有了captcha的key,所以源代码中的check()方法必然会返回false,暂时我的做法是注释掉了这一段代码 // $this->session->remove('captcha'); 然后在登陆的控制器里加上: session()->remove('captcha'); 如果还不放心的话,可以在前端js里给captcha的img添加一个click()事件,让captcha刷新一下.

现在ajax异步验证并提交表单一切OK!

In English: I found the cause and found a solution The reason for the occurrence of false using Ajax post asynchronous authentication is that, after the input authentication code is submitted for post submission(for example, a lost focus post event is bound), the source code performs the action of clearing the session, and the source code is:$this->session->remove('captcha') In this case, when you click on the form submission, there is no captcha key in the session, so the check () method in the source code will definitely return false, and for the time being I'm commenting on the missing piece of code // $this->session->remove ('captcha');' Then add the controller to the landing: session () ->remove ('captcha'); If you're still worried, you can add a click () event to the captcha's img in the front of the JS to refresh the captcha

Now Ajax asynchronously validates and submits the form, all OK!

By.istheprince

shanhai3000 avatar Sep 03 '17 22:09 shanhai3000

@istheprince 请问一下,laravel5.5的版本,按照您的方法操作,还是验证失败,有遇到过这种情况吗?

sheaxiang avatar Sep 14 '17 02:09 sheaxiang

@sheaxiang 我就在用5.5,你是什么情况呢?

shanhai3000 avatar Sep 16 '17 21:09 shanhai3000

还有一种解决方式。通过修改app/Http/Kernel.php中的middleware如下:

protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\Cors::class,
        \Illuminate\Session\Middleware\StartSession::class, // 将Session添加到每一个请求中
    ];

其他内容都不需要修改,即可解决ajax验证码验证的问题。

heimuya avatar Nov 24 '17 06:11 heimuya

@istheprince 请问一下, 5.1版本,注释掉了 $this->session->remove('captcha'),控制器添加了 session()->remove('captcha');,使用 ajax 还是返回 false。这是还需要做哪些步骤吗

tsurumure avatar Dec 12 '17 07:12 tsurumure

Thanks zhangqi1990! I was having trouble with an Ajax contact form and your answer Sep 3, 2017 was the answer that fixed my problem along with explanation of why the check() method was firing. I implemented your fix and now the form works as users would expect.

jcanchor avatar Apr 07 '18 15:04 jcanchor

@heimuya
laravel5.6中的$middleware中加上\Illuminate\Session\Middleware\StartSession::class, // 将Session添加到每一个请求中,我再vue中使用的代理请求接口还是验证返回失败?? public function check($value) { if ( ! $this->session->has('captcha')) { return false; } ..... } 这个方法中直接返回false;

qingyi12345 avatar Sep 07 '18 07:09 qingyi12345

how i can get captcha value ?? which is generated?

singhsnt avatar Dec 04 '18 09:12 singhsnt

how i can get captcha value ?? which is generated?

Set up your config/app.php file properly:

Package service providers Mews\Captcha\CaptchaServiceProvider::class,

Aliases 'Captcha' => Mews\Captcha\Facades\Captcha::class,

Then in your form you can call: <?php echo Captcha::img('flat'); ?>

The img options are defined in your config/captcha.php file where you can find these options: default, flat, mini or inverse

See the instructions and details for setup on the <> code page for more ways to use the package.

jcanchor avatar Dec 04 '18 18:12 jcanchor

okay i will try. I need captcha to match user entered captcha and generated captcha same then validate and user register sucessfully

On Wed, Dec 5, 2018 at 12:10 AM Jim Adamek [email protected] wrote:

how i can get captcha value ?? which is generated?

Set up your config/app.php file properly:

Package service providers Mews\Captcha\CaptchaServiceProvider::class,

Aliases 'Captcha' => Mews\Captcha\Facades\Captcha::class,

Then in your form you can call:

The img options are defined in your config/captcha.php file where you can find these options: default, flat, mini or inverse

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mewebstudio/captcha/issues/108#issuecomment-444209994, or mute the thread https://github.com/notifications/unsubscribe-auth/Ako8NPj_YCADFBLWt9iR1hlP1826ATrNks5u1sGXgaJpZM4PG82X .

singhsnt avatar Dec 05 '18 07:12 singhsnt

is captcha value stored in session??

On Wed, Dec 5, 2018 at 1:25 PM vikas singh [email protected] wrote:

okay i will try. I need captcha to match user entered captcha and generated captcha same then validate and user register sucessfully

On Wed, Dec 5, 2018 at 12:10 AM Jim Adamek [email protected] wrote:

how i can get captcha value ?? which is generated?

Set up your config/app.php file properly:

Package service providers Mews\Captcha\CaptchaServiceProvider::class,

Aliases 'Captcha' => Mews\Captcha\Facades\Captcha::class,

Then in your form you can call:

The img options are defined in your config/captcha.php file where you can find these options: default, flat, mini or inverse

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mewebstudio/captcha/issues/108#issuecomment-444209994, or mute the thread https://github.com/notifications/unsubscribe-auth/Ako8NPj_YCADFBLWt9iR1hlP1826ATrNks5u1sGXgaJpZM4PG82X .

singhsnt avatar Dec 05 '18 08:12 singhsnt

if not how i can store it in session and than i can get it??

On Wed, Dec 5, 2018 at 1:48 PM vikas singh [email protected] wrote:

is captcha value stored in session??

On Wed, Dec 5, 2018 at 1:25 PM vikas singh [email protected] wrote:

okay i will try. I need captcha to match user entered captcha and generated captcha same then validate and user register sucessfully

On Wed, Dec 5, 2018 at 12:10 AM Jim Adamek [email protected] wrote:

how i can get captcha value ?? which is generated?

Set up your config/app.php file properly:

Package service providers Mews\Captcha\CaptchaServiceProvider::class,

Aliases 'Captcha' => Mews\Captcha\Facades\Captcha::class,

Then in your form you can call:

The img options are defined in your config/captcha.php file where you can find these options: default, flat, mini or inverse

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mewebstudio/captcha/issues/108#issuecomment-444209994, or mute the thread https://github.com/notifications/unsubscribe-auth/Ako8NPj_YCADFBLWt9iR1hlP1826ATrNks5u1sGXgaJpZM4PG82X .

singhsnt avatar Dec 05 '18 08:12 singhsnt

if not how i can store it in session and than i can get it??

You can check your session variables in controller that processes your form with:
dd($request, Session::All());

You can add your captcha variable to session with: Session::put('captcha', $captcha);

Refer to https://laravel.com/docs/master/session#using-the-session or

https://learninglaravel.net/cheatsheet/#sessions

jcanchor avatar Dec 05 '18 18:12 jcanchor

Thanks jim. Problem is solved

On Wed, Dec 5, 2018 at 11:31 PM Jim Adamek [email protected] wrote:

if not how i can store it in session and than i can get it??

You can check your session variables in controller that processes your form with: dd($request, Session::All());

You can add your captcha variable to session with: Session::put('captcha', $captcha);

Refer to https://laravel.com/docs/master/session#using-the-session http://url or

https://learninglaravel.net/cheatsheet/#sessions http://url

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mewebstudio/captcha/issues/108#issuecomment-444582570, or mute the thread https://github.com/notifications/unsubscribe-auth/Ako8NJgR7U2ajyRKxJQVCnQg67FvX2lzks5u2AoBgaJpZM4PG82X .

singhsnt avatar Dec 06 '18 04:12 singhsnt