Ir para o conteúdo

Sistema login com parâmetros

Introdução

A classe destina-se a um sistema de login direccionado a parâmetros, evitando assim o tão conhecido SQLinjection. Derivado ao tipo de programação introduzida neste artigo (OOP), não é preciso um conjunto de funções e estratagemas para evitar intrusos mal-intencionados. Temos um exemplo bem vivo na Wiki sobre como ultrapassar intrusos sem a utilização de parâmetros: Login Seguro.

Mas o mesmo artigo torna-se bastante extenso e confuso algumas vezes pela quantidade de funções utilizadas para ofuscar todo o tipo de vulnerabilidades.

Fica desde já o código SQL para a criação da tabela:

CREATE TABLE  `teste`.`registos` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`email` TEXT NOT NULL ,
`password` TEXT NOT NULL
) ENGINE = INNODB;

Class Login

A classe trata, para além do login, de outros factores tais como prolongamento do utilizador no site (cookies/sessões) assim como logout do mesmo.

Login

function log_in() {
        $this->email = $_POST['email'];
        $this->password = $_POST['password'];

        $db = new mysqli($this->host, $this->huser, $this->hpass, $this->hdatabase);
        /* Caso seja necessário especificar o charset que provém da base de dados:
         * $db->set_charset("utf8");
         */
        if ($db->connect_errno) {
            printf("Erro ao connectar: " . $db->connect_error);
            exit();
        }

        $query = $db->prepare("SELECT id FROM registos WHERE email = ? AND password = ?");
        $query->bind_param("ss", $this->email, $this->password);
        /* s = string ; s = string
         * email = s; password = s;
         */
        $query->execute();
        $query->store_result(); // Detecta se existem registos
        $query->bind_result($result); // Guarda o valor do ID
        $query->fetch();

        if ($query->num_rows() > 0) {
            $this->id = $result;
            $_SESSION['email'] = $this->email;
        $_SESSION['id'] = $this->id;
        setcookie("email", $this->email, time() + 3600); // 1 hora
        } else {
            die('Email/Password errados.');
        }

        $query->close();
        $db->close();
    }

Cookies/Sessões

Não explorei todas as vantagens dos cookies, como é o caso do caminho, domínio, etc. Explorei o básico em conjunto com as sessions, mas deixo o tutorial do mesmo.

Logout & Blocked

function log_out() {
        setcookie("email", "", time() - 3600);
        session_start();
        session_destroy();
        header('location: index.php');
    }

A função blocked tem como fim bloquear o acesso às páginas caso não se esteja devidamente identificado (login).

function blocked() {
        session_start();
        if (empty($_SESSION['login'])) {
            header('location: index.php');
        }
    }

Código Final

Class login {

    private $host = 'localhost';
    private $huser = 'root';
    private $hpass = '';
    private $hdatabase = 'teste';
    private $email;
    private $password;
    private $id;

    function log_in() {
        $this->email = $_POST['email'];
        $this->password = $_POST['password'];

        $db = new mysqli($this->host, $this->huser, $this->hpass, $this->hdatabase);
        /* Caso seja necessário especificar o charset que provém da base de dados:
         * $db->set_charset("utf8");
         */
        if ($db->connect_errno) {
            printf("Erro ao connectar: " . $db->connect_error);
            exit();
        }

        $query = $db->prepare("SELECT id FROM registos WHERE email = ? AND password = ?");
        $query->bind_param("ss", $this->email, $this->password);
        /* s = string ; s = string
         * email = s; password = s;
         */
        $query->execute();
        $query->store_result(); // Detecta se existem registos
        $query->bind_result($result); // Guarda o valor do ID
        $query->fetch();

        if ($query->num_rows() > 0) {
            $this->id = $result;
            $_SESSION['email'] = $this->email;
            $_SESSION['id'] = $this->id;
            setcookie("email", $this->email, time() + 3600);
        } else {
            die('Email/Password errados.');
        }

        $query->close();
        $db->close();
    }

    function log_out() {
        setcookie("email", "", time() - 3600);
        session_start();
        session_destroy();
        header('location: index.php');
    }

    function blocked() {
        session_start();
        if (empty($_SESSION['login'])) {
            header('location: index.php');
        }
    }

}

Main Page

Na página principal deve-se fazer uma verificação simples para perceber se o utilizador já está autenticado ou não, vai um exemplo simples:

<div id="login" style="border-style: solid; border-width: 1px">
            <form id="login" method="POST">
            <?php
                session_start();
                if (empty($_SESSION['login'])) {
                    ?>
                    email:
                    <input type="Text" name="email"/>
                    password:
                    <input type="password" name="password"/>
                    <input type="checkbox" name="remember"/>
                    <input type="Submit" value="OK" name="sub_login"/>
              <?php
                } else {
                    ?>
                    <input type="Submit" value="Logout" name="sub_log_out"/>
              <?php
                }
                ?>
            </form>
        </div>

Depois é só verificar qual o botão pressionado:

include('login.php');
$log = new login;
if (isset($_POST['sub_login'])) {
    $log->log_in();
}
if (isset($_POST['sub_log_out'])) {
    $log->log_out();
}