Rosa Mystica
Rosa Mystica

Reputation: 253

Forced user logout in case of internal errors in cakephp3.0

I am using cakephp 3.0 ,In my application I want forced user logout or clear session in case if any internal error occurs,How can I accomplish it. Can I make any changes in the error controller and will it able to catch the specific internal errors.

Upvotes: 0

Views: 166

Answers (1)

Reactgular
Reactgular

Reputation: 54791

CakePHP uses the ErrorController to render HTTP responses for both unhandled exceptions and fatal errors. Keep in mind that it's also used for 404 not found exceptions.

You can logout the user in ErrorController in the beforeFilter event, and render the error message as normal. Afterwards their session will have ended.

I give you a warning. The ErrorController should be kept as simple as possible. Should not perform heavy logic. The reason is very simple. If you generate a fatal error inside ErrorController it creates an endless loop.

Most people configure their AuthComponent in their base AppController which you should never extend as the base class for ErrorController.

That means you have to configure the AuthComponent separately in your ErrorController and hope it never fails and you keep the configuration consistent with what you have in AppController.

If you go that route. Also wrap your code in a try/catch block to prevent exceptions from being thrown from inside the ErrorController.

For example;

public function beforeFilter(Event $event)
{
    try {
        $this->Auth->logout();
    }catch(\Exception $ex) {
        // prevent endless loop
    }
}

Alternative perform a 302 redirect:

It's better to keep ErrorController as vanilla as possible and not load the AuthComponent inside it. I assume you have a controller already set up for logging users in and out. Add a new route for that controller called "forced_out", and then redirect the URL to that route when there is an uncaught exception. Inside the action for "forced_out" you can log the current user out.

Create a new error handler class like this.

class ForceOutErrorHandler extends ErrorHandler {
    protected function _displayException($exception)
    {
         // restore the old handler
         (new ErrorHandler(Configure::read('Error')))->register();

         throw new RedirectException(Router::url([
            'controller'=>'Users',
            'action'=>'forced_out'
         ));
    }
}

Now register that error class only when a user is signed in. You can do this in the beforeFilter of your AppController like this:

public function beforeFlter(Event $event) {
     if($this->Auth->user()) {
        (new ForceOutErrorHandler(Configure::read('Error')))->register()
     }
}

Note: I'm not sure if CakePHP will catch the redirect exception from inside the error handler like that or not. You might have to use header(); die() as a last try.

Upvotes: 1

Related Questions