PHP Session through MVC

Question!

I'm having trouble understanding how the session works with php through mvc. My spaghetti code worked like a charm, and implementing it in mvc gives me trouble. I can successfully log in. The problem is keeping a session for the logged in user, and displaying e.g the logout button.

My login view:

<div class="container">
    <div class="login"><br>
        <h4>Login</h4>
        <?php
            echo "<form method='POST' action='login-user.inc.php'>
                  <form class='login-inner'>
                        <input type='text' name='username' placeholder='Username' autocomplete='off' /><br /><br />
                        <input type='password' name='password' placeholder='Password' /><br /><br />    
                        <input class='button' type='submit' name='submit' value='Login' />
                </form>
        </form>";
        ?>
    </div>
</div>

The login view goes through the login-user.inc.php:

<?php
namespace View;

use \Controller\SessionManager;
use \Util\Util;
use \Exceptions\CustomException;

require_once 'mvc/Util/Util.php';
Util::initRequest();

$messageToUser = "";
$controller = "";

if(isset($_POST['username']) && isset($_POST['password']) && !isset($_POST[Util::USER_SESSION_NAME])){
    if(!empty($_POST['username']) && !empty($_POST['password'])){
        $username = htmlentities($_POST['username'], ENT_QUOTES);
        $password = htmlentities($_POST['password'], ENT_QUOTES);

        try{
            $controller = SessionManager::getController();
            $controller->loginUser($username, $password);
            echo "<p class = 'positiveMessageBox'>You are logged in! :) Welcome!</p>";
        }catch(CustomException $ex){
            echo "<p class = 'warningMessageBox'>".$ex->getMessage()."</p>";
        }catch(\mysqli_sql_exception $ex){
            echo "<p class = 'negativeMessageBox'>An error in connection with database occurred! Please contact administration of this website.</p>";
        }finally{
            SessionManager::storeController($controller);
        }
    }else{
        echo "<p class = 'warningMessageBox'>Both username field and password field have to be filled! Try again!</p>";
    }
}

@$_GET['page'] = $_SESSION['pageId'];
include Util::VIEWS_PATH."redirect.php";
?>

My sessionhandler.php:

<?php
namespace Controller;

use Controller\Controller;

/**
 * This class stores and retrieves session data
 * @package Controller
 */
class SessionManager{
    const CONTROLLER_KEY = 'controller';
    const BROWSER_COMMENT_COUNT_KEY = 'browserCommentsCount';

    private function __construct(){}

    /**
     * This method stores controller instance in the current session
     * @param \Controller\Controller $controller
     */
    public static function storeController(Controller $controller){
        $_SESSION[self::CONTROLLER_KEY] = serialize($controller);
    }

    /**
     * This method returns Controller instance
     * If Controller instance do not exists then returns new instance
     * @return \Controller\Controller
     */
    public static function getController(){
        if(isset($_SESSION[self::CONTROLLER_KEY]))
            return unserialize($_SESSION[self::CONTROLLER_KEY]);
        else
            return new Controller();
    }
}
?>

My util, that is first and last initialized with the session_start():

<?php
namespace Util;

/**
 * Utility class
 * @package Util
 */
final class Util{
    const VIEWS_PATH = 'src/view/';
    const CSS_PATH = 'src/css/';
    const IMG_PATH = 'src/img/';
    const USER_SESSION_NAME = 'username';

    private  function __construct(){}

    /**
     * This method initialises autoload function and starts session
     * This method should should be called first in any PHP page that receiving a HTTP request
     */
    public static function initRequest(){
        \session_start();


        self::initAutoload();
    }

    private static function initAutoload(){
        spl_autoload_register(function($class) {
            require_once 'mvc/' . \str_replace('\\', '/', $class) . '.php';
        });
    }
}
?>

This goes through the controller etc. This is what happens after a successful login.

public function login(LoginData $userLoginData){
    $userDAO = new UserDAO();

    if($userDAO->doUsernameExistInDB($userLoginData->getUsername())){
        if(password_verify($userLoginData->getPassword(), $userDAO->getUserPasswordFromDB($userLoginData->getUsername()))){
            session_regenerate_id();
            $_SESSION['username'];
        }else
            throw new CustomException("Password do not match with username you entered!");
    }else{
        throw new CustomException("We could not find the username you entered.");
    }
}

And finally the redirect.php that is supposed to show the logout button:

<?php
if (!empty($_SESSION[\Util\Util::USER_SESSION_NAME]))
    {
        echo '<li><a href="logout-user.inc.php">Logout</a><br><a>Welcome '.$_SESSION[\Util\Util::USER_SESSION_NAME].'</a></li>';
    } else {
        echo '<li><a href="index.php?page=login">Login</a><br><a href="index.php?page=register">Register</a></li>';
    }   
?>

I'm wondering why a session isn't initialized when logging in. It keeps telling me that I can still log in, when I already have. What am I missing here?

By : Einstein


Answers

In your login function, you seem to just call the $_SESSION['username'].

Shouldn't you be affecting it the username of the connected user ?

Then, in your redirect.php, when you're checking \Util\Util::USER_SESSION_NAME which corresponds to username, it must be empty, and then always shows the 'Login' button.

Hope this helps !



This video can help you solving your question :)
By: admin