We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

csrf problem with angular js

hello i have a problem when i am submiting a form with angular (ng-submit) with ajax call to the controller the token check desent work if i cancel the token check the submit successfully , i saw the discation in https://forum.phalcon.io/discussion/1547/csrf-dont-work-with-json-requests

in the form i use :

    <input type="hidden" name="{{ security.getTokenKey() }}" value="{{ security.getToken() }}" >

then i submit with angular the form with http.post in the controller i did :

    $post   =   $this->request->getJsonRawBody();
    foreach($post as $postName => $postValue) {
            $_POST[$postName]   =   $postValue;
    }
    if($post && $this->security->checkToken())  {

    }

bat it desnt work for me, anyone have a solution??



1.5k
Accepted
answer

Hi @itamar727, here's an example that works (tested in version v1.3.0)...

The view:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sample angular submit</title> 
    <script src="https://code.jquery.com/jquery-2.0.1.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
</head>
<body ng-app="">
    <script>
        function Ctrl($scope, $http) {
            $scope.formData = {
                username: null,
                email: null,
                token: null,    
            };

            $scope.submit = function() {    
                $scope.formData.token = [$("#token").attr("name"), $("#token").val()];      

                $http.post(
                    'test', 
                    JSON.stringify($scope.formData)
                ).success(function(data) {
                    if (data.isValidToken) {
                        alert("Ok, you win!!!");
                    } else {
                        alert("Sorry, not valid CSRF !!!")
                    }
                });
                return false;
            };
        }
    </script>

    <form ng-submit="submit()" ng-controller="Ctrl">
        <label>Name:</label>
        <input type="text" ng-model="formData.username" name="username" />
        <label>Email:</label>
        <input type="text" ng-model="formData.email" name="email" />
        <input type="hidden" id="token" name="<?php echo $this->security->getTokenKey() ?>" value="<?php echo $this->security->getToken() ?>" />

        <input type="submit" id="submit" value="Submit" />
    </form>
</body>
</html>

The controller action:

public function testAction()
{
  if ($this->request->isPost()) {
    $this->view->disable();

    $data = $this->request->getJsonRawBody();
    $data->isValidToken = $this->security->checkToken($data->token[0], $data->token[1]);

    $this->response->setContentType('application/json', 'UTF-8');
    $this->response->setContent(json_encode($data));
    $this->response->send();
  }
}

And Remember to add a session adapter to your Dependency Injector, otherwise the token check won’t work:

$di->setShared('session', function() {
    $session = new Phalcon\Session\Adapter\Files();
    $session->start();
    return $session;
});

I hope it works for you.