Redirect page and display error - workflow help

Hello all,

I have this method like so:


public function verificaLogin($nivelAcesso, $pURL = false)
    {
        //se nao houver variável de sessão setada ou se o nível de utilizador for menor que o nível de acesso:
        if (!isset($_SESSION['idUtilizador']) OR ($_SESSION['nivelUtilizador'] < $nivelAcesso))
        {
            // Destrói a sessão
            session_destroy();

            // e redirecciona para url
            if ($pURL)
            {
                Funcao::redirecciona($pURL);
            }

            $this->_msgErro = 'A página pretendida é de acesso restrito. A sessão expirou. Faça login novamente. Obrigado';
        }
    }

Later on this class I have this method:

/**
     *
     * @return string
     * @desc mostra mensagem de erro setada num dos métodos da classe.
     */
    public function mostraMsgErro()
    {
        return $this->_msgErro;
    }

I would then have something like this on my login page:

<?php echo (isset($resultado['insucessoLogin'])) ? '<div id="login-erro"><span>'.$resultado['insucessoLogin'].'</span></div>':''; ?>

The intended result is to display that specific method error message, on the page that the user has been redirected to.

But I’m lost now.
Somewhere I will need to have this:

$resultado['insucessoLogin'] = mostraMsgErro();

But I’m not quite sure were to put it… :s

Can I have a push here… :sick:

Thanks in advance,
Márcio

If you’re initializing _msgErro in your object definition, then wont isset() always return true (even though it’s null)? Try it with empty() instead?

Can you elaborate a little bit more here, where should we include de login page?
Die on what condition?

Yes… I’ve thought about this, but then, why do I need a method on my class to display the errors. (and this is already working for those cases when redirect isn’t need it) :s - Plus, of course, the URL length limits.

What about a session var?

And there is an issue about knowing how much time we should put or message on, if we put it too long, the user can leave. If we put to short, the user can’t read. It’s more difficult and present even more issues.

That’s why I was thinking on sessions, but I’m not getting how can we relate the class method, and the message that THAT method could return, and the place were we can set that session variable…

Another (very stupid) option, could be to redirect to different login pages based on the method that is running. But this is, out of question of course…

:injured:

Ok… if I change my redirect method like this:


   /**
    *
    * @param <string> $pURL
    * @param <string> $paramURL
    */
    static function redirecciona($pURL, $paramURL = null)
    {
        if (strlen($pURL) > 0)
        {
            if (headers_sent())
            {
                if(!$paramURL)
                {
               
                    echo "<script>document.location.href='".$pURL."';</script>\
";
                }
                else
                {
                    echo "<script>document.location.href='" .$pURL. "?msg=" .$paramURL. "';</script>\
";
                }
            }

        }
        else
        {
            if (!$paramURL)
            {
                //o espaço após os : é important! cf. HTTP/1.1 standard, section 4.2
                header("Location: " . $pURL);
            }
            else
            {
                header("Location: " . $pURL . '?msg='.$paramURL);
            }
   
        }

    }

And then add url query strings on my restricted page:

require_once("../Controller/Utilizador.Controller.php");

//instancia o DAO
$utilizadorDao = new UtilizadorDao();

//instancia o login
$login = new Login($utilizadorDao);

//aqui tem de estar o parametro ?msg
$login->verificaLogin(2, 'index.php?msg=erro')

And then I add this on my login form page:

<?php echo (isset($_GET['msg'])) ? '<div id="login-erro"><span>A página pretendida é de acesso restrito. A sessão expirou. Faça login novamente. Obrigado</span></div>':''; ?>

I get the desired message.

However the message is hardcoded :s, and I would like to have it displayed, depending on the error messages defined on Login class methods.

When the session expires, returns a message = ‘session expire’; when the user is trying to access using a direct link without login = “you need to do login first”, etc…

K. Regards,
Márcio

I have change the class method do return either true or false, is this the best way for doing it ?

/**
     *
     * @param <int> $nivelAcesso
     * @param <string> $pURL
     * @return <boolean>
     * @desc Verifica se existe sessão, com um determinado nível de acesso. Se não existe, redirecciona.
     */
    public function verificaLoginIndevido($nivelAcesso = 0, $pURL = false)
    {
        //se nao houver variável de sessão setada ou se o nível de utilizador for menor que o nível de acesso:
        if (!isset($_SESSION['idUtilizador']) OR ($_SESSION['nivelUtilizador'] < $nivelAcesso))
        {
            // Destrói a sessão
            session_destroy();

            // e redirecciona para url
            if ($pURL)
            {
                Funcao::redirecciona($pURL);
            }

            $this->_msgErro = 'A página pretendida é de acesso restrito. A sessão expirou. Faça login novamente. Obrigado';

            return true;
        }
        else
        {
            return false;
        }
    }

Then on Utilizador.Controller I have put this:


//se a query string msg no URL estiver definida:
if(isset($_GET['msg']))
{
    //instancia o DAO
    $utilizadorDao = new UtilizadorDao();

    //instancia o login
    $login = new Login($utilizadorDao);

    
    if ($login->verificaLoginIndevido() === true)
    {
        $resultado['insucessoLogin'] = $login->mostraMsgErro();
    }
}

Now I get the messages defined on the Object method.

However:
The fact that we need to hard code this query strings seems no good:

$login->verificaLoginIndevido(2, 'index.php?msg=erro');

Any suggestions?

My Utilizador.Controller (that is NOT a class, because I don’t know how use it, if it was), looks a little bit BIG for such a simple login methods, and I have code repeated that I will try to shrink, but, any suggestions to make it shrink?

/*
 * Nota: o caminho é referente, não a este ficheiro, mas ao ficheiro onde este ficheiro está a ser incluído.
 * Isto é, relativo à view (ao local onde são colocados os inputs do utilizador).
 */
include_once("../Model/Dao/UtilizadorDao.class.php");
include_once("../Model/Dao/UtilizadorVo.class.php");
include_once("../Helper/Login/Login.class.php");

$resultado=array();


/**
 * Login
 */

//se houve submit:
if(isset($_POST['login']))
{
    //instancia um Value Object:
    $utilizadorVo = new UtilizadorVO();

    //seta os valores do form para no Value Object:
    $utilizadorVo->setNome(stripslashes($_POST['inputUtilizador']));
    $utilizadorVo->setPassword(stripslashes($_POST['inputPassword']));

    //instancia o DAO
    $utilizadorDao = new UtilizadorDao();

    //instancia login, passando o data access object:
    $login = new Login($utilizadorDao);

    $pURL = 'InserirNoticia.php';

    //se não houve login:
    if ($login->loginUtilizador($utilizadorVo, $pURL) === false)
    {
        $resultado['insucessoLogin'] = $login->mostraMsgErro();
    }
    else
    {
        $login->loginUtilizador($utilizadorVo, $pURL);
    }
}

//se a query string msg no URL estiver definida:
if(isset($_GET['msg']))
{
    //instancia o DAO
    $utilizadorDao = new UtilizadorDao();

    //instancia o login
    $login = new Login($utilizadorDao);

    
    if ($login->verificaLoginIndevido() === true)
    {
        $resultado['insucessoLogin'] = $login->mostraMsgErro();
    }
}

Thanks in advance,
Márcio

I have removed the fixed message and I have placed on Utilizador.Controller.

So, now, on the login form page I have this:

<?php echo (isset($resultado['insucessoLogin'])) ? '<div id="login-erro"><span>'.$resultado['insucessoLogin'].'</span></div>':''; ?>

And depending on the contents of this array, the message will change.

On my Controller.Utilizador I have:


if(isset($_GET['msg']))
{
    $resultado['insucessoLogin'] = 'some message bla bla';
}[

So, if a URL param is passed, I get this.

The only thing that needs to be done now is to have this message coming from our Login Object Instance.

But I’m getting always NULL so, I believe it doesn’t even get out of here:


/**
     *
     * @param int $nivelAcesso
     * @param string $pURL
     *
     * @desc Verifica se existe sessão, com um determinado nível de acesso. Se não existe, redirecciona.
     * 
     */
    public function verificaLogin($nivelAcesso, $pURL = false)
    {
        //se nao houver variável de sessão setada ou se o nível de utilizador for menor que o nível de acesso:
        if (!isset($_SESSION['idUtilizador']) OR ($_SESSION['nivelUtilizador'] < $nivelAcesso))
        {
            // Destrói a sessão
            session_destroy();

            //THIS ERROR MESSAGE SEEMS TO NOT PASS INTO THE mostraMsgErro() METHOD.
            $this->_msgErro = 'A página pretendida é de acesso restrito. A sessão expirou. Faça login novamente. Obrigado';

            
            
            // e redirecciona para url
            if ($pURL)
            {
                Funcao::redirecciona($pURL);
            }

        }
    }

 /**
     *
     * @return string
     * @desc mostra mensagem de erro setada num dos métodos da classe.
     */
    public function mostraMsgErro()
    {
        return $this->_msgErro;
    }

:nono:

So there are a couple of ways this can go;

1: Instead of re-locating the user, include_once() the login page and then die() afterwards (The way i’d do it, but i’m not usually an OOP Programmer)
2: Pass the message as a param-string on the URL, and have the login page echo it if it exists. (Makes the message visible on the URL, though)
3: Recode the redirect to show the error message for x seconds and then then fire the redirect (more difficult)


/**
    *
    * @param <string> $pURL
    * @param <string> $paramURL
    */
    static function redirecciona($pURL)
    {
        if (strlen($pURL) > 0)
        {
            if (headers_sent())
            {
               
                    echo "<script>document.location.href='".$pURL."';</script>\
";
              
            }

        }
        else
        {
            
                //o espaço após os : é important! cf. HTTP/1.1 standard, section 4.2
                header("Location: " . $pURL);
   
        }

    }

That was my first attempt, to add a new argument to this function, like $paramURL and, if it was set, it displays… but I got lost on the process, and end up reverting it… :s

Thanks a lot for your time into it,
Márcio

To answer this question, I need to know the code for Funcao::redirecciona($pURL);

Your problem seems to be that your redirection isnt passing the error message on.

True. :s

Yes, except on the login page, I have this on my restrict pages:


require_once("../Controller/Utilizador.Controller.php");

//instancia o DAO
$utilizadorDao = new UtilizadorDao();

//instancia o login
$login = new Login($utilizadorDao);

$login->verificaLogin(2, 'index.php');

That’s the issue. The verification has been made, it returns to the login page, but no message is displayed. Should we store the return result on a session variable and add it to the code above? By putting it on a session, if it’s set, It can then display something on our login page?

If that’s the path, I’m not yet getting how can we set the session properly, because, if we do:


require_once("../Controller/Utilizador.Controller.php");

//instancia o DAO
$utilizadorDao = new UtilizadorDao();

//instancia o login
$login = new Login($utilizadorDao);

if ($login->verificaLogin(2, 'index.php'))
{
    $_SESSION['acessoErro'] = $login->mostraMsgErro();
};

I believe that, what is inside this last conditional will never run, because the method verificaLogin() redirects to index.php before if can run what is inside the conditional.
So we will need a way to set the message, uppon verification, but before redirecting.

So, we should edit the verificaLogin method instead perhaps?


public function verificaLogin($nivelAcesso, $pURL = false)
    {
        //se nao houver vari&#225;vel de sess&#227;o setada ou se o n&#237;vel de utilizador for menor que o n&#237;vel de acesso:
        if (!isset($_SESSION['idUtilizador']) OR ($_SESSION['nivelUtilizador'] < $nivelAcesso))
        {
            // Destr&#243;i a sess&#227;o
            session_destroy();

            // e redirecciona para url
            if ($pURL)
            {
                Funcao::redirecciona($pURL);
            }

            $this->_msgErro = 'A p&#225;gina pretendida &#233; de acesso restrito. A sess&#227;o expirou. Fa&#231;a login novamente. Obrigado';
        }
    }

But if we remove the $this->_msgErro = ‘my message’, and we replace for something like:

public function verificaLogin($nivelAcesso, $pURL = false)
    {
        //se nao houver vari&#225;vel de sess&#227;o setada ou se o n&#237;vel de utilizador for menor que o n&#237;vel de acesso:
        if (!isset($_SESSION['idUtilizador']) OR ($_SESSION['nivelUtilizador'] < $nivelAcesso))
        {
            // WE NEED TO REMOVE THIS
            //session_destroy();

            //Before redirecting:
            $_SESSION['errorMsg'] = 'A p&#225;gina pretendida &#233; de acesso restrito. A sess&#227;o expirou. Fa&#231;a login novamente. Obrigado';

            // and then redirect
            if ($pURL)
            {
                Funcao::redirecciona($pURL);
            }

            
        }
    }

This will avoid the all process of using a showErrorMsg method…

Please advice, :shifty:
Márcio


<?php echo (isset($resultado['insucessoLogin'])) ? '<div id="login-erro"><span>'.$resultado['insucessoLogin'].'</span></div>':''; ?>

If you set this up using


$resultado['insucessoLogin'] = mostraMsgErro(); 

then $resultado[‘insucessoLogin’] WILL exist, so your if will always evaluate to true.

It sounds to me like what you actually want to do is call verificaLogin() on -every- page (to see if their session has expired), and then do something like


<?php echo ($session->mostraMsgErro() == null) ? '<div id="login-erro"><span>'.$session->mostraMsgErro().'</span></div>':''; ?>

Sorry, can you elaborate a little bit more?

Thanks in advance,
Márcio

I could try to pass a parameter to the url redirect directly, by adding this string '?error=‘expire’ ; then on the login page, I can have something that says, if isset(get[‘error’]) and get error = ‘expire’, display the error. ?

I will give it a try…

But then of course, I need a way to make this work with the class method that displays the errors. (why oh why I’m I insisting on this? Because I would like to do it the best OOP way I can).

Dying,
Márcio