AdamW

419 when submitting live forms displayed through pusher

Posted 1 month ago by AdamW

In my application a user can create a challenge that is then submitted to another user.

Example: playerA sends a challenge to playerB. PlayerB can either accept or decline this challenge. Once playerA sends a challenge to playerB, I refresh the web page (logged in as playerB) and I can see the challenge from playerA. I can now accept or decline this challenge and everything works good.

Now when playerA creates a challenge I fire an event in the controller that will automatically display the challenge to playerB via pusher without the need for a page refresh. So as soon as playerA sends a challenge to playerB, playerB can now see this challenge without needing to refresh the page. All working good so far.

Now the problems start. If playerB tries to decline or accept the challenge (that has appeared through pusher) the page redirects and displays a 419 error. If playerB refreshes the page the challenge can be declined or accepted as normal. The problem only occurs when a player is responding to a challenge that has been displayed through pusher. If a challenge is loaded through a page refresh the forms will work fine.

This is what part of my code looks like to display the decline challenge form through pusher:

var receivedChallengesWrapper   = $('#kt_tabs_5_3');
var receivedChallenges          = receivedChallengesWrapper.find('.kt-portlet__body');

Pusher.logToConsole = true;
var pusher = new Pusher('XXXXXXXXX', {
    authEndpoint: 'pusher/auth',
    auth: 
    {
        headers: 
           {
                'X-CSRF-Token': '{{ csrf_token() }}'
       }
    },
    cluster: 'eu',
    encrypted: false
});

var privatechannel = pusher.subscribe('private-receivedChallenges-{{ Auth::user()->id }}');

privatechannel.bind('receivedChallenges', function(data) 
{
var existingReceivedChallenges  = receivedChallenges.html();
var newReceivedChallengeHtml = 
`
    <form class="kt-form pull-right" method="POST" action=" 
    {{action('[email protected]')}}">
    <input type="hidden" name="challengeid" value="`+data.gameid+` ">
    <button class="btn btn-label-danger btn-outline-danger btn-sm btn-upper btn-submit-declinechallenge"><i class="fa fa-trash-alt"></i> decline</button>
    </form> 
`;
receivedChallenges.html(newReceivedChallengeHtml + existingReceivedChallenges);
receivedChallengesWrapper.show(); 
}

Here is my AJAX code to submit the form:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

$(".btn-submit-declinechallenge").click(function(e){
    e.preventDefault();

    let form = $(this).parent();
    let challengeid = jQuery('input[name="challengeid"]').val();

    $.ajax({
        type:'POST',
        url: form.attr('action'),
        data: form.serialize(),

    success:function(data){
        if(data.successful) {
            toastr.success(data.successful);
        }
        if(data.error) {
                toastr.error(data.error);
        }

        jQuery.each(data.errors, function(key, value){
            jQuery('#'+key+'-error-border-openchallenge').addClass('is-invalid')
            jQuery('#'+key+'-error-text-openchallenge').show();
            jQuery('#'+key+'-error-text-openchallenge').append('<p>'+value+'</p>');
        });
    }

    });
});

If i submit the form after displaying it through a page refresh it works fine. If i try to submit the form as soon as it has been displayed through pusher I get the 419.

CSRF token is in the head.

<meta name="csrf-token" content="{{ csrf_token() }}" />

I suspect this may be due to the JS being unable to select $(this).parent(); when the form is displayed through pusher without the page refresh. Maybe something to do with the DOM, really not sure. Any help would be appreciated.

Please sign in or create an account to participate in this conversation.