title: PHP authentication and authorization
body: <p>I've got a front controller which routes all the requests to their related Controller.</p>
  
  <p>Now, I need to implement a structure like <strong>USERS - ROLES - SERVICES</strong>, where in Services I should put those things that the users can or cannot do (e.g. deleting a product).</p>
  
  <p><code>Users</code>, <code>Roles</code> and <code>Services</code> have to be persistent in db.</p>
  
  <p>This is my <strong>front controller</strong> (<code>index.php</code>):</p>
  
  <pre><code>/* index.php is the front controller (something like a global controller
   * which routes all the requests to their relative controllers) */
  require_once 'init.php';
  require_once ROOT_DIR . "/controllers/DocumentController.php";
  require_once ROOT_DIR . "/controllers/UserController.php";
  require_once ROOT_DIR . "/resources/SMTemplate.php";
  
  /* Pass an empty $contents array to the controller.
  * The controller fills it with its contents and gives it back to the template. */
  $contents = Array();
  
      $requestedUrl = $_SERVER['REQUEST_URI'];
      $parsedRequestedUrl = parse_url($requestedUrl,PHP_URL_PATH);
      $parsedRequestedUrl = strtolower($parsedRequestedUrl); // Lo mette tutto in minuscolo in modo tale da non avere problemi di case sensitiveness
      $uri1Parts = explode("/", $parsedRequestedUrl);
  
      if (isset($uri1Parts[3])){
          $controllerString = $uri1Parts[3];
  
          if (isset($uri1Parts[4])) {
              $methodString = $uri1Parts[4];
              // if ($methodString)
          } else {
              $methodString = '';
          }
      } else {
          $controllerString = '';
      }
  
  
  
  switch ($controllerString) {
  
      case '':
          $controller = new DocumentController($contents);
          $template = $controller-&gt;goToIndex();
          $contents = $controller-&gt;getContents();
          break;
  
      case 'documents':
          $controller = new DocumentController($contents);
          switch ($methodString) {
  
              case '':
                  $template = $controller-&gt;viewDocuments();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'documentslistforsharer':
                  $template = $controller-&gt;documentslistforsharer();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'listdocumentsresponsegrid':
                  $responseGrid = $controller-&gt;listDocumentsResponseGrid(); // in realtà ne esce un echo per ajax
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'create_start':
                  $template = $controller-&gt;createStart();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'create':
                  $redirect = $controller-&gt;createDocument();
                  $contents = $controller-&gt;getContents();
                  break;
          }
          break;
  
      case 'users':
          $controller = new UserController($contents);
          switch ($methodString) {
  
              case '':
                  $template = $controller-&gt;goToIndex();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'create_start':
                  $template = $controller-&gt;createStart();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'create':
                  $template = $controller-&gt;createUser();
                  $contents = $controller-&gt;getContents();
                  break;
  
              case 'authenticate':
                  $contents = $controller-&gt;getContents();
                  $redirect = $controller-&gt;authenticateUser();
                  //$template = $controller-&gt;authenticateUser();
  
                  break;
          }
          break;
  }
  
  /* If the controller call returns a value in a $template variable, the front controller
  * renders the template. If the value is returned in a $redirect variable, the front
  * controller redirects the user to the url inside it. */
  
  if (isset($template)) {
      $tpl = new SMTemplate();
      $tpl-&gt;render($template,$contents);
  } elseif (isset($redirect)) {
      $parsedUrl = parse_url($redirect,PHP_URL_PATH);
      $urlParts = explode("/", $parsedUrl);
      $redirectMethod = $parts[4];
      // Checks if the fourth level of the url refers to the authenticate method or not.
      if ($redirectMethod == "authenticate") {
          header("Location: http://localhost/blabla");
          exit();
      } else {
          header("Location: " . $redirect);
          exit();
      }
  }
  </code></pre>
  
  <p>How can I implement the <strong>USERS - ROLES - SERVICES</strong> structure?</p>
  
  <p>Should I fill Services table in db with urls like "<em>documents/create</em>" and check if the user+role has got that service? I don't like it very much...I thought that authentication should have been done in specific Controllers, non in the front controller.</p>
  
  <p>What do you suggest?</p>