1

I'm sending data from a form with AJAX. The data is a username and password of the user, and therefore I want to make it as secure as possible.

I'm trying to use a token as an extra security layer, but it always return as "invalid".

I've gone through https://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms and can't see that anything should be wrong.

My login form:

<form method="post" action="#" id="userForm">
    <label for="username">Brugernavn</label>    
    <input type="text" value="" name="username">    
    <label for="password">Password</label>  
    <input type="password" value="" name="password">
    <?php echo JHtml::_( 'form.token' ); ?>
    <button id="login-user">Login</button>
</form>

The AJAX request:

jQuery.ajax({
    url: 'index.php?option=com_content&format=ajax&view=article&task=loginUser&tmpl=component',
    type: 'post',
    dataType: 'html',
    data: {
        form: jQuery(form).serializeArray()
    },
    async: true,
    success: function(response){
        console.log(response);
        var result = response;

        if ( result.loggedIn == 1 ) {                   
            //User logged in
            jQuery('#loginModal').modal('hide');
        }
        else {                  
            //User not logged in                
        }               
    }
}); 

The function that gets called in my view.ajax.php

public function _logInUser( $form ){

    $options = array();
    $credentials = array();

    var_dump($form);
    JSession::checkToken() or die( 'Invalid Token' );
    $credentials['username'] = $form[0]['value'];
    $credentials['password'] = $form[1]['value'];

    $result = JFactory::getApplication()->login($credentials, $options);        
    $result = ($result) ? 1 : 0;

    //1     - logged in
    //0     - not logged in     
    echo json_encode( array('loggedIn' => $result) );                   
    jexit();

}

And the output in my console from var_dump($form);

array(3) {
  [0]=>
  array(2) {
    ["name"]=>
    string(8) "username"
    ["value"]=>
    string(20) "myusername@something.dk"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(8) "password"
    ["value"]=>
    string(8) "mypassword123"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(32) "dc56f674238905e70ab3d98f9bb6e2f0"
    ["value"]=>
    string(1) "1"
  }
}
Invalid Token

The only thing else I can think of, is that &format=ajax or dataType: 'html' should be something like json or maybe raw ...but when I tried that, then the call dosen't work at all.

2

By default JSession::checkToken() checks the post request for a value named the token. It can also be set to look for get values in a query string like JSession::checkToken('get'). It doesn't know that a variable you've serialized manually in a structure you built yourself and called 'form' is where to find the token.

To test it manually you could do something like the following:

if ($form[2]['name'] != JSession::getFormToken()){die();}

I haven't tested that but I don't see why it shouldn't work. Once a csrf token is made for the session it generally stays the same.

  • Thanks!! Works :) ...I don't understand why this is not an example on the Joomla documentation under "Checking the Token"... It only says "use JSession::checkToken() or die( 'Invalid Token' );" – JonasB Oct 13 '18 at 7:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.