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.
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.
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.
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.
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.
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.
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( ... )
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( ... )
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:
URL:
/index.php/ccm/foo
You don't have to install anything, unlike the single page.
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'),
Viewing 15 lines of 17 lines. View entire code block.
URL:
/index.php/ccm/foo
You don't have to install anything, unlike the single page.
https://www.concrete5.org/community/forums/usage/external-form-redir...
https://documentation.concrete5.org/developers/working-with-blocks/c...