Welcome Guest, Not a member yet? Register   Sign In
redirect() in base controller
#1

Hi,
In my baseController I've got a function that check if user's role is compatible with the controller's roles.
Here is this function :
PHP Code:
function check(array $roles) {
       
        
if (!isset($_SESSION['role'])) {
            die("<p>Aucun rôle défini. Vous ne pouvez accéder à cette fonctionnalité.</p>");
        }
        else {
            if (in_array($_SESSION['role'], $roles)) {
                return TRUE;
            } else {
                return redirect()->to("http://localhost/g/public/index.php/");
                die("<p>Vous ne pouvez accéder à cette fonctionnalité.</p>");
            }
        }
    
This function works but not the redirection. If user's role isn't in $roles redirection doesn't apply.
I read and search about using redirect function in basecontroller but wasn't able to find a solution.

Any idea ?
If you think that I'm trying to do it in a wrong way tell it to me.

Thanks
Reply
#2

If you want to redirect, you must return a RedirectResponse object from the controller.
Does the controller return a RedirectResponse object?
Reply
#3

(This post was last modified: 03-16-2023, 06:18 AM by sTis.)

Thank for your answer.
I saw that in ci4 documentation but.. I'm not sure how to do that.
Could you explain it please ?

Function check is in standard baseController.
Reply
#4

The constructor method __construct() cannot return values.
It is the specification in PHP language.

And initController() in CI4 Controller also cannot return values.
Reply
#5

Thanks for your clues !

I succeeded by changing two three things. I'm not sure that the best way to do it but it works.
I've loaded "response" as a service. Can't succeeded to make it works with "redirectResponse".

Instead of creating a new function in baseController I choose to create a library GAuthLib.

If the specialists can give me an opinion. I will be very grateful.

My baseController :

Code:
<?php

namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\RedirectResponse;
use Psr\Log\LoggerInterface;

/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
*    class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*/
abstract class BaseController extends Controller
{
    /**
    * Instance of the main Request object.
    *
    * @var CLIRequest|IncomingRequest
    */
    protected $request;

    /**
    * An array of helpers to be loaded automatically upon
    * class instantiation. These helpers will be available
    * to all other controllers that extend BaseController.
    *
    * @var array
    */
    protected $helpers = [];

    /**
    * Constructor.
    */
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        // Do Not Edit This Line
        parent::initController($request, $response, $logger);

        // Preload any models, libraries, etc, here.

        $this->session = \Config\Services::session();

        $this->authLib = new \App\Libraries\GAuthLib;
    }


}

My auth library :

Code:
<?php

namespace App\Libraries;

class GAuthLib {

    public function checkAccess(array $roles) {
        $config = config('thisApp');

        $response = \config\Services::response();

        // No role : redirection
        if (!isset($_SESSION[$config->appName]['user']['role'])) {
            return redirect()->to(site_url('init/index'));
            die("<p>No role defined.</p>");
        }
        // Got role. Check if controller accept this role.
        else {
            if (in_array($_SESSION[$config->appName]['user']['role'], $roles)) {
                return TRUE;
            } else {
                return $response->redirect(site_url('home/index'))->send();
                die("<p>No right ! Can't access.</p>");
            }
        }
    }

   
}


And my test controller :

Code:
function testRole() {
        $this->authLib->checkAccess(["dir"]); // Tests roles and redirect if not compatible.

        echo "access granted";
    }
Reply
#6

Somebody can help ??? What I'm I doing wrong ??
I'm still on my way to achieve my function checkRole working correctly.
Kenjis said it must return an redirectResponse object.
So I've changed my library.
I replace $response = \config\Services::response(); by $redirectResponse = \config\Services::redirectresponse();

Here is my code :

PHP Code:
<?php

namespace App\Libraries;

class 
GAuthLib {

    public function checkAccess(array $roles) {
        $config config('thisApp');
        $redirectResponse = \config\Services::redirectresponse();

        // No role : redirection
        if (!isset($_SESSION[$config->appName]['user']['role'])) {
            return $redirectResponse->to(site_url('auth/index'));
            die("<p>No role defined.</p>");
        }
        // Got role. Check if controller accept this role.
        else {
            if (in_array($_SESSION[$config->appName]['user']['role'], $roles)) {
                return TRUE;
            } else {
                return $redirectResponse->to(site_url('home/index'));
                die("<p>No right ! Can't access.</p>");
            }
        }
    }

    

But redirection doesn't work.

$redirectResponse->to() return a redirectResponse object (I think !!).
Here is a dump on it (just a part) :
PHP Code:
C:\wamp64\www\g\app\Libraries\GAuthLib.php:15:
object(CodeIgniter\HTTP\RedirectResponse)[89]
  protected 'protocolVersion' => string '1.1' (length=3)
  protected 'validProtocolVersions' => 
    array (size=3)
      0 => string '1.0' (length=3)
      1 => string '1.1' (length=3)
      2 => string '2.0' (length=3)
  protected 'body' => null
  
protected 'headers' => 
    array (size=3)
      'Cache-control' => 
        object(CodeIgniter\HTTP\Header)[90]
          protected 'name' => string 'Cache-control' (length=13)
          protected 'value' => 
            array (size=3)
              ...
      'Content-Type' => 
        object(CodeIgniter\HTTP\Header)[92]
          protected 'name' => string 'Content-Type' (length=12)
          protected 'value' => string 'text/html; charset=UTF-8' (length=24)
      'Location' => 
        object(CodeIgniter\HTTP\Header)[93]
          protected 'name' => string 'Location' (length=8)
          protected 'value' => string 'http://localhost/g/public/index.php/home/index' (length=46

So if someone can explain me how to achieve this function working correctly...
Thanks
Reply
#7

You should use a Filter for redirecting.

SEE:
Controllers and Routing Controller Filters
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#8

Your code doesn't return anything.
Yes, your library returns some result, but the controller in which this library is called does not return the result of the library.
Reply
#9

Hi,
@InsiteFX :
I tought about filter but...
checkAccess function need parameters that are different for each controller.
I explain : each controller list, in an array, roles that can access it.
How can I, in a filter, do this ? I thought to do it in routes definition but I'm not sure how to make it work.

@iRedds :
Thank, I will explore this way.
Reply
#10

(This post was last modified: 04-19-2023, 02:55 AM by Muzikant.)

(03-16-2023, 04:02 AM)kenjis Wrote: If you want to redirect, you must return a RedirectResponse object from the controller.

I am strugling whit this too. There should be a simple example in a documentation of how to use it. For example:

PHP Code:
$redirectResponse = \config\Services::redirectresponse();
return 
$redirectResponse->redirect('home/index'); 

Is it a recommended way of using it?
Reply




Theme © iAndrew 2016 - Forum software by © MyBB