AJAX for Logged-In Users

Permalink
Hi all,
Feeling more stuck than usual.

I'm trying to build a simple site that will only be available to logged-in users. I have a Single Page set up with a custom controller that returns some JSON formatted data. The controller has a few actions, including "list_all_for_product". "list_all_for_product" takes an Express ID for a product, then outputs a list of "tests" associated with the product in JSON.

If I log in, then open a new tab and load the URL:
http://<internal IP>/index.php/testplan/list_all_for_product/3
I get beautiful, beautiful JSON.

If I log out and load the same URL, I get a log-in page, obviously.

The problem: If I log in and fetch the page using JavaScript in an existing page, the fetch command receives a log-in page.

I don't see anything about security in the documentation about Single Page controllers. I'm following the examples pretty closely. My best guess is that I need a CSRF token of some kind, but I can't find any information about CSRF tokens in Concrete5.

 
linuxoid replied on at Permalink Reply
linuxoid
FreddyVsJson replied on at Permalink Reply
Thanks! That wasn't the issue, but it got my brain working again, and I realized I hadn't set the "credentials" property on the fetch.

fetch(url, {
credentials: 'same-origin',
mode: 'same-origin'
}).then( ... ).then( ... )

And of course, I now need the information you gave me to make sure my functioning fetches can't be abused.
jero replied on at Permalink Reply
jero
A CSRF token won't help here - the issue you have is that your single page is apparently restricted to logged in users, and you're trying to access it before you have actually logged in.

A CSRF token merely generates a value that's sent with the request, and the controller method is supposed to check that it matches. It's got no concept of user login or user id.

You say "If I log in and fetch the page using JavaScript in an existing page"

Can you explain a bit more about what you're doing exactly. It's most probably a timing
issue.

If your single page only needs to return JSON, then I'd ask why you're using a single page at all?

You might want to consider creating a controller (in application/controllers) together with a route
added to application/config/app.php, or add a route from a custom package.
FreddyVsJson replied on at Permalink Reply
I haven't used the route stuff before. It seemed more complicated than adding a Singe Page with a controller (at least in the sense that it used features I'm less familiar with).

It turns out I had forgotten to set the "credentials" option in the fetch for the millionth time.

For anyone else either spacing out or new to fetch:
fetch(url, {
credentials: 'same-origin',
mode: 'same-origin'
}).then( ... ).then( ... )
jero replied on at Permalink Reply
jero
Sounds like you have it sorted.

I wouldn't say it was more complicated to use rooutes. Here's the absolute basics:

application/controllers/foo.php:
<?php
namespace Application\Controller;
use Controller;
class Foo extends Controller {
        public function view () {
// your code here
        }
}
[/code[
application/config/app.php:
[code]
<?php
return [
        'routes' => [
                "/ccm/foo" => array('\Application\Controller\Foo::view'),


URL:
/index.php/ccm/foo

You don't have to install anything, unlike the single page.