I am creating my own Arastta theme.
With the route=account/address/edit where i can edit an address, i am having the problem that once that i finished editing an address and press the
continue button, i get to a blank page saying this:

Invalid CSRF token.

Any idea where this token must be checked or set?
Thanks and greetings and good night
In Themes
Monday, May 15 2017, 02:50 AM
Share this post:

Accepted Answer

Tuesday, May 16 2017, 01:29 AM - #Permalink
Those are the event names you are seeing, so for example postAppRoute resolves to event name post.app.route. Or rather event post.app.route resolves to the function.

I use vscode for dev with php plugins and i simply do a search for the string, so in this case 'postAppRoute' and then I set a breakpoint in /catalog/event/app/crsf.php where this function is defined and investigate the variables and what the function does.

public function postAppRoute(){}

Hope this helps

Darren
The reply is currently minimized Show
Responses (6)
  • Accepted Answer

    Monday, May 15 2017, 03:43 AM - #Permalink
    Hi,


    Events are discussed here

    https://arastta.org/docs/developers/event-system

    Looks like the /system/library/app.php file listens for a post.app.route event fired in /system/library/app/catalog.php on all route requests.

    Note the event naming scheme, so the "post.app.route" event fired in (/system/library/app/catalog.php) resolves to postAppRoute function.

    In the postAppRoute function shown below (defined in /catalog/event/app.php) it checks if its a POST, and then runs some logic to see if its empty, does the route exist in the config file as a CRSF route and does the token exist. If it doesn't exist, or validate then it dies with the msg you described.

    So this fires on all route requests (i.e navigation requests).


    public function postAppRoute()
    {
    // Check if the request is POST and route is not empty
    if (!$this->request->isPost() || empty($this->request->get['route'])) {
    return;
    }

    // Check if route is in the the check list
    if (!in_array($this->request->get['route'], $this->config->get('config_sec_csrf'))) {
    return;
    }

    // Validate CSRF token
    if (CSRF::validate($this->request->post, $this->token_name)) {
    return;
    }

    die('Invalid CSRF token.');
    }
    Like
    1
    The reply is currently minimized Show
  • Accepted Answer

    Monday, May 15 2017, 04:02 AM - #Permalink
    oops forgot to mention

    in /event/app/crsf.php the event exists that sets the token.


    class EventAppCsrf extends Event
    {

    private $token_name = 'csrf_token';

    public function postLoadView(&$output, $template)
    {
    // Check if the output is POST and route is not empty
    if (empty($output) || empty($this->request->get['route'])) {
    return;
    }

    // Check if route is in the the check list
    $route = $this->request->get['route'];

    if (!in_array($route, $this->config->get('config_sec_csrf')) || !strstr($template, $route.'.tpl')) {
    return;
    }

    // Add CSRF token
    $input = CSRF::getHiddenInputString($this->token_name);

    $output = str_replace('', $input.'', $output);
    }


    This is called by /system/engine/loader.php in the view function (as shown below):

    Note the $this->trigger->fire('post.load.view', array(&$output, $template)); line

    This fires for all load view requests, so if the view exists, then the postLoadView function is called which sets the CSRF token.


    public function view($template, $data = array()) {
    $theme_dir = Client::isCatalog() ? 'theme' : 'template';

    if (Client::isAdmin() && isset($this->session->data['theme']) && $this->session->data['theme'] != 'advanced') {
    if (file_exists(Client::getDir() . 'view/theme/' . $this->session->data['theme'] . '/template/' . $template)) {
    $theme_dir = 'theme/' . $this->session->data['theme'] . '/template';
    }
    }

    $file = Client::getDir() . 'view/' . $theme_dir . '/' . $template;

    if (file_exists($file)) {
    $this->trigger->fire('pre.load.view', array(&$template, &$data));

    extract($data);

    ob_start();

    require($file);

    $output = ob_get_contents();

    ob_end_clean();

    $this->trigger->fire('post.load.view', array(&$output, $template));

    return $output;
    } else {
    trigger_error('Error: Could not load template ' . $file . '!');
    exit();
    }
    }



    As far as I can tell, all this stuff is managed through the event system.

    EDITED:
    Quoted code to make it more readable.
    Like
    1
    The reply is currently minimized Show
  • Accepted Answer

    Monday, May 15 2017, 04:08 AM - #Permalink
    Make sure you activate debug mode as well, as this (I believe) will show the events that are fired and will make troubleshooting much easier.

    https://arastta.org/docs/how-to/how-to-activate-debug-mode

    From the event name, you can translate this to the event itself by adding a fullstop between e.g

    post.load.view - postLoadView function
    Like
    1
    The reply is currently minimized Show
  • Accepted Answer

    Monday, May 15 2017, 12:48 PM - #Permalink
    Thanks a lot for your answers!
    I am just wondering as i have done this:
    1. copied the whole template folder content from the default template
    2. pasted it into my own template folder
    3. Adapted it to my needs

    When i realized that it did not worked, i simply did step 1 and 2 again and tried it out without changing anything.
    And here also the error appears, or in other words: can someone check if the defalt "edit address" page works?

    I will turn debug on and see if i get some more information there.

    Hugs and greetings from this corner of the planet,
    Carlos
    The reply is currently minimized Show
  • Accepted Answer

    Monday, May 15 2017, 02:39 PM - #Permalink
    All i get from the debugging is this:

    Trigger 0.000 seconds (+0.000); 0.00 MB (0.000) - postAppInitialise
    Trigger 0.023 seconds (+0.023); -0.15 MB (-0.146) - postAppEcommerce
    Trigger 0.036 seconds (+0.013); -0.14 MB (+0.002) - preAppSslredirection
    Trigger 0.047 seconds (+0.011); -0.14 MB (+0.001) - postAppRoute
    Trigger 0.074 seconds (+0.027); -0.08 MB (+0.067) - preLoadLanguage
    Trigger 0.093 seconds (+0.020); -0.07 MB (+0.001) - postLoadLanguage
    Trigger 0.110 seconds (+0.016); -0.07 MB (+0.001) - preLoadModel
    Trigger 0.119 seconds (+0.009); -0.07 MB (+0.002) - postLoadModel
    Trigger 0.131 seconds (+0.012); -0.07 MB (+0.006) - preLoadController
    Trigger 0.149 seconds (+0.019); -0.06 MB (+0.005) - preLoadView
    Trigger 0.170 seconds (+0.021); -0.06 MB (+0.001) - postLoadView
    Trigger 0.181 seconds (+0.011); -0.06 MB (-0.000) - postLoadController
    Trigger 0.227 seconds (+0.046); -0.05 MB (+0.014) - preLoadHeader
    Trigger 0.241 seconds (+0.014); -0.05 MB (+0.001) - postLoadHeader
    Trigger 0.303 seconds (+0.062); -0.01 MB (+0.037) - preCatalogLayoutPosition
    Trigger 0.352 seconds (+0.049); -0.02 MB (-0.006) - postAppDispatch
    Trigger 0.361 seconds (+0.009); -0.02 MB (+0.000) - postAppRender

    Is there a way to get a more detailed debugging, like for example what data is passed?
    The reply is currently minimized Show
  • Accepted Answer

    Friday, August 18 2017, 08:23 PM - #Permalink
    Good afternoon,
    Analyzing the above error I verified that during the execution of the method that inserts the csrf token to the form it applies the following validation:

            if (!in_array($route, $this->config->get('config_sec_csrf')) || !strstr($template, $route.'.tpl')) {
    return;
    }


    In the case of the route: "account/address/edit"
    The template is: "second/template/account/address_form.tpl"
    !strstr($template, $route.'.tpl')

    For this route validation will never be true because the template does not follow the pattern of the route.
    The reply is currently minimized Show
Your Reply