Securing access to the API (custom keys)

In reading through the documentation - Custom API Tokens, I saw that it was advisable to limit access to data by using custom keys and specifying which endpoint the token is valid for.

Thus, this (in Settings > API access):

API-Key: f82XXXXXXXXXXXXXXXXXXXXbs3
Rules: /api/collections/get/shop/

Will only allow access to Shop data by going to this address: /api/collections/entries/shop?token=f82XXXXXXXXXXXXXXXXXXXXbs3 ! If I try to access the Portfolio data with the same token (/api/collections/entries/portfolio?token=f82XXXXXXXXXXXXXXXXXXXXbs3), it will return an error.

Great ! But I want to go one step further.

I want to use the filter / sort parameters (example: /api/collections/entries/shop?token=f82XXXXXXXXXXXXXXXXXXXXXXXXbs3&filter[published]=true&sort[order]=1).

So, if the filter / sort parameters are missing or are different from what was originally intended, I want it to return an error. Otherwise, I want it to return the data.

Is this possible?

I can’t find this kind of information in the documentation.

Thanks for advance.

The following source could be used as READ rule file and would set a fixed filter and sort setting. Should be plenty to play around with.

<?php

if (COCKPIT_API_REQUEST) {
  $options = &$context->options; 
  $options['filter'] = ['publish' => true];
  $options['sort'] = ['order' => 1];
 
}

Thanks for the feedback.

Indeed, it works.

Now, when I go to the address: /api/collections/entries/shop, I only have all the published items, sorted in the right order.

However, if later, I need to get the list of all the items (published or not), still sorted in the right order… I thought I could use a token to bypass the rule set upstream: /api/collections/entries/shop?token=f82XXXXXXXXXXXXXXXXXXXXXXXXbs3&sort[order]=1

But it gives me the same result as without the token (only the list of published items, sorted in the right order).

It is not possible to cumulate the two behaviours ?

I see. You want to distinguish between “authenticated” users (via token) and “the public”.

Unfortunately there is no “was-authenticated-by-valid-custom-token”-flag set when the user is using a registered custom token. Only if an account token was used that user would be logged in and we could use that later as a means of saying “this is currently an authenticated api call”.

But a simple, hardcoded solution could be the following:

<?php

namespace CustomApiReadRule0;

// exchange this function for a more complex variant of checking if the currently used token is valid or not
function isValidToken($token)
{
    if ($token === "f82XXXXXXXXXXXXXXXXXXXXXXXXbs3") {
        return true;
    }

    return false;
}

if (COCKPIT_API_REQUEST) {
    global $cockpit;
    $options = &$context->options;

    $token = $cockpit->param('token', null);

    // preset filter if not authenticated via valid token or filter is missing
    if (!isValidToken($token) || !isset($options['filter'])) {
        $options['filter'] = ['publish' => true];
    }
    // auto-set sorting if not preset
    if (!isset($options['sort'])) {
        $options['sort'] = ['order' => 1];
    }

}