Authentication plugin - allow access to home page

Hi,

I’ve finished the authentication tutorial. I want to modify the system so that you don’t have to be logged in to visit the home page, and you do have to be logged in to view and list pages.

Obviously, you don’t want to call addUnauthenticatedActions(‘display’), because then none of the pages that the Pages controller displays will require authentication. So, I added a function to the Pages controller (going from memory here, as I don’t have the code handy at the moment, so ignore any typos):

public function displayHomePage(): Response
{
    return $this->display('home');
}

I changed the AppController beforeFilter call to addUnauthenticatedActions:

    $this->Authentication->addUnauthenticatedActions(['displayHomePage']);

and updated the route route to the home page:

... ['/' => ['controller' => 'Pages', 'action' => 'displayHomePage'] ...

Is that an appropriate way to do that? Is there a better way?

I guess I could make it more generic, and rename displayHomePage to displayUnauthenticatedPage, and accept a parameter:

    public function displayUnauthenticatedPage($page): Response
    {
        //TODO: error handling - if $page is null, empty, or not in a list of accepted
        // unauthenticated pages, throw an exception
        return $this->display($page)
    }

Thoughts and comments?

This is $this->render('home')
And the $this->Authentication->allowUnauthenticated([]) can be in the PagesController::initialize()

How does this look:

    private static $unauthenticatedPages = ['home'];
    public function displayUnauthnPage($pageToDisplay): Response
    {
        if ( !$pageToDisplay || !in_array($pageToDisplay, PagesController::$unauthenticatedPages) ) {
            throw new ForbiddenException();
        }
        try {
            return $this->render($pageToDisplay);
        } catch (MissingTemplateException $exception) {
            if (Configure::read('debug')) {
                throw $exception;
            }
            throw new NotFoundException();
        }
    }

Ah, putting the call to allowUnauthenticated in the initialize function makes sense. The tutorial puts it in beforeFilter for both AppController and UsersController. Should the tutorial be amended?

You could allow the display method conditionally.

public function beforeFilter(\Cake\Event\EventInterface $event): void
{
    parent::beforeFilter($event);

    $allowedPages = ['home', 'foo', 'bar/baz'];

    $path = implode('/', $this->request->getParam('pass'));
    if(in_array($path, $allowedPages, true)) {
        $this->Authentication->allowUnauthenticated(['display']);
    }
}
1 Like