Check for Preview-Token in Controller

I’ve setup a website with virtual pages from DB everything works as expected but when i open a page of a draft without token the page still gets displayed.

now if’ve added a controller and redirect to the 404 page when the page is not published. this works also. but when i’m in the panel and like to preview the draft page i get a 404 error because the controller doesn’t care about the token.

now i like to check in my controller if a token exists and show the page if it exists.

i use the following code

<?php

return function ($page) {
    if (null !== Url::query('token')) {
        if (!$page->isPublished()) {
            echo page('error')->render();
            exit();
        }
    };
};

this code doesn’t work because i can’t get the Token Parameter from the URL in the controller.

is there a way to solve that? i couldn’t find anything in the docs or forum.

To get your code sample to work, you need to replace Url::query('token') with get('token').

However, this code is not checking that the token is valid – any URL containing a non-empty token parameter would give access to the preview. Maybe this thread helps investigating further, if that’s what you need; sounds like a check for being logged-in – something like if(kirby()->user()) – might be the easiest, whereas generating and validating a bespoke token for a virtual page might be tricky …but maybe somebody more knowledgeable might still chime in with a suggestion here?

first thanks for your fast reply.

this didn’t worked, with get(‘token’), the token was always null.
isn’t get() getting the parameters from the url with name:value?
but the token is set with ?token=value

i’ve changed the code to check if the user is logged in like this

return function ($page,$kirby) {
    $user = kirby()->user();
    if ($user == null) {
        if (!$page->isPublished()) {
            echo page('error')->render();
            exit(); 
        }
    };
};

this works but including a token check or validation would be great.

Does your model handle the draft related methods correctly?

yes, it does.

Hmm… I tried this in a template and it worked. get() retrieves the attribute-value pairs of the URL query. Maybe try kirby()->request()->get('token) instead? (as get() is a shorthand for that, but I can’t really imagine why that helper wouldn’t be available in a controller as is.)

But indeed, this does not really solve the quest for proper validation :slightly_frowning_face:

$kirby->request()->get(‘token’) doesn’t work neither, maybe because it’s in the controller and not the template.

get('token') should work, you can easily test this by putting this sample code into your controller

   if($token = get('token')) {
        dump($token);
    }

And opening your page by appending ?token=123.

Using the Token in the url:
grafik

with your code

 if($token = get('token')) {
        dump($token);
    }

Results in null

dump not triggered and debugger shows null aswell:
grafik

Which Kirby version are you using?

i’m on 3.5.6

Just out of curiosity: does get('foo') return something for you if you visit “page?foo=bar” ?