Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

janokary's avatar

Laravel 5.2. login with ajax form

I use laravel 5.2 build in auth, but when in the login form I use ajax. When I post something that is not valid according to the validator I get a 422 response. Fine. But the email or the credentials are not right I don't. So what I did is in vendor/laravel/framework/src/illuminate/Foundation/Auth in AuthenticatesUsers.php and I altered the

protected function sendFailedLoginResponse(Request $request)
{
    return redirect()->back()
        ->withInput($request->only($this->loginUsername(), 'remember'))
        ->withErrors([
            $this->loginUsername() => $this->getFailedLoginMessage(),
        ]);
}

to

protected function sendFailedLoginResponse(Request $request)
{
  if ($request->wantsJson()) {
    return response([
      'ok' => false,
      'success' => false,
      'message' => $this->getFailedLoginMessage()
    ],422);
  };
    return redirect()->back()
        ->withInput($request->only($this->loginUsername(), 'remember'))
        ->withErrors([
            $this->loginUsername() => $this->getFailedLoginMessage(),
        ]);
}
0 likes
5 replies
christopher's avatar

You dont need to change any methods since laravel is returning the stuff with json. This is my personal ajax login.

$('#login-form button[type=submit]').click(function(e){


    var $btn = $(this).button('loading');

    e.preventDefault();

    if($('#login-form #login--email').hasClass('has-error')){
        $('#login-form #login--email').removeClass('has-error');
    }

    if($('#login-form #login--password').hasClass('has-error')){
        $('#login-form #login--password').removeClass('has-error');
    }

    var form = jQuery(this).parents("form:first");
    var dataString = form.serialize();
    var formAction = form.attr('action');

    $.ajax({
        type: "POST",
        url : formAction,
        data : dataString,
        success : function(data){
            console.log(data);

            setTimeout(
                function()
                {
                    $btn.button('success');
                    $('#login-form button[type=submit]').css('background', '#449d44');

                    setTimeout(
                        function()
                        {
                            window.location.href = "/dashboard";

                        }, 2000);

                }, 2000);

        },
        error : function(data){
            var errors = $.parseJSON(data.responseText);
            console.log(errors);

            setTimeout(
                function()
                {

                    errorsHtml = '<div class="alert alert-danger text-center"><h4 class="margin-top-20" style="font-size: 18px;"><i class="fa fa-exclamation"></i> Bitte prüfen Sie Ihre Eingaben</h4><p style="color:#35393b">Bitte korrigieren Sie Ihre Angaben</p><ul class="list-unstyled">';
                    $.each( errors , function( key, value ) {
                        errorsHtml += '<li style="color:#35393b;">' + value[0] + '</li>'; //showing only the first error.
                    });
                    errorsHtml += '</ul></di>';

                    $( '#form-errors' ).html( errorsHtml ); //appending to a <div id="form-errors"></div> inside form

                    if(errors.email){
                        $('#login-form #login--email').addClass('has-error');
                        $('#login--email i').css('color', '#a94442');
                    }

                    if(errors.email){
                        $('#login-form #login--password').addClass('has-error');
                        $('#login--password i').css('color', '#a94442');
                    }

                    $btn.button('reset');

                }, 1500);

        }

    },"json");
});
1 like
janokary's avatar

I use vue-resource that is waiting for the proper response header. So if you give a wrong email you won't get an error response but success. Changing this ( vendor/laravel/framework/src/illuminate/Foundation/Auth in AuthenticatesUsers.php ) solved my error, but I have to write another class override class to just override this one.

janokary's avatar

So, to override this vendor method properly I wrote it in app/Http/Controllers/Auth/AuthController.php ( and made use of Illuminate\Http\Request ).

jekinney's avatar
Level 47

@janokary By default auth attempt returns true or false. Obviously if a validation error it returns a 422 before running auth attempt.

I don't use the default auth controller as I would be over riding almost everything.

Just run the auth attempt in a if statement if false return a different error code. I'ld go with 406 not acceptable. In your vue resource error check obviously you check the status for a 422, add a check for 406 and out put what error message you need.

public function login(Request $request)
{
    //Validation as needed or form request
    if(!auth()->attempt($credentials, $remember)
    { 
        return abort(406);
    }
    // else user is logged in
    return redirect()->intended();
}

Vue JS

this.$http.post('url to post', logindata).then(function (response) {
          // success callback
      }, function (response) {
          if(response.status == 422) {
        'failed validation';
    } else if(response.status == 406) {
        'wrong input, can't login';
    }
      });

1 like
dkruger's avatar

@janokary if you still are using L5.2 may I recommend you using this as well for handling validation, Laravel-Bootstrap-Modal-Form

Beside this, had to overwrite the sendFailedLoginResponse to my AuthController.php.

protected function sendFailedLoginResponse(Request $request) {

    if ($request->wantsJson()) {
        return response([
            'email' => [ $this->getFailedLoginMessage() ]
        ], 422);
    };

    return redirect()->back()
        ->withInput($request->only($this->loginUsername(), 'remember'))
        ->withErrors([
            $this->loginUsername() => $this->getFailedLoginMessage(),
        ]);
}

as you did, and had to include as well

use Illuminate\Http\Request;

Please or to participate in this conversation.