Ir para o conteúdo

Criar um sistema de login básico em PHP e MySQL

Quase todas as pessoas que aprendem PHP se deparam com a necessidade de fazer uma página em que o utilizador tem de estar autenticado perante o sistema. Uma das maneiras clássicas de o fazer é usando a combinação username/password para verificar um utilizador. Neste artigo, vamos ver como é fácil criar um sistema de login simples, sem nunca descurar um factor fundamental: segurança.

Assume-se que o utilizador já tem conhecimentos de SQL e de tópicos em PHP como sessões.

Base de dados

Para poder armazenar os utilizadores, é necessário que estes estejam numa base de dados. Vamos ver como criar a estrutura e adicionar alguns utilizadores.

Estrutura

No mínimo, iremos precisar de um username e de uma password por utilizador. A nossa tabela pode ser feita da seguinte forma:

CREATE TABLE users (
  userid int NOT NULL PRIMARY KEY AUTO_INCREMENT,
  username varchar(50) NOT NULL UNIQUE,
  password varchar(40) NOT NULL
)

Com este comando, criamos uma tabela chamada users, que possui 3 colunas: userid, que irá identificar univocamente o utilizador na base de dados; username, que irá conter o nome de utilizador, limitado a 50 caracteres; password, vai conter a síntese da password.

O tamanho do campo password é 40 caracteres, porque este é o número de caracteres devolvidos pela função SHA1. Não é necessário alterar este tamanho, mas se for necessário, nunca deverá ser inferior a 40.

Importante: De notar que o campo password irá conter não a password em texto plano, mas sim a sua síntese, após ser submetida à função SHA1. Desta forma, garante-se confidencialidade da password, caso haja algum ataque à base de dados, pois o atacante apenas fica a conhecer a síntese, e não a password exacta.

Adicionar utilizadores

Vamos agora adicionar alguns utilizadores à base de dados. O comando pode ser alterado conforme o pretendido, desde que se respeite sempre a sintaxe SQL, e pode ser executado tantas vezes quanto o número de utilizadores que pretendemos adicionar:

INSERT INTO users (username,password) VALUES ('administrador', SHA1('1234'));

Este comando de SQL insere na tabela um utilizador com o nome de utilizador administrador e com a palavra-passe 1234, que serão mais tarde usadas no login. Os valores podem ser mudados para outros à escolha.

Como nota, a função do MySQL SHA1 vai substituir a password que escolherem pela sua síntese, síntese essa que irá ser guardada na base de dados. Exemplificando, a password 1234, após submetida à função SHA1, gera a síntese 7110eda4d09e062aa5e4a390b0a572ac0d2c0220. Este último valor vai ser guardado na base de dados, para fins de comparação.

Criar uma página para login

Definida a nossa base de dados, vamos criar uma página de login muito simples.

login.php

<html>
<head>
  <title>Login b&aacute;sico com PHP</title>
</head>
<body>
  <form action="processaLogin.php" method="POST">
    <p>Username: <input type="text" name="username" /></p>
    <p>Password: <input type="password" name="password" /></p>
    <p><input type="submit" name="submit" value="Login" /></p>
  </form>
</body>
</html>

Em seguida, criamos uma página que irá tratar do login, e de verificar se o utilizador introduzido está ou não correcto.

processaLogin.php

<?php
// começar ou retomar uma sessão
session_start();

// se vier um pedido para login
if (!empty($_POST)) {

    // estabelecer ligação com a base de dados
    mysql_connect('hostsql', 'username', 'password') or die(mysql_error());
    mysql_select_db('basedados');

    // receber o pedido de login com segurança
    $username = mysql_real_escape_string($_POST['username']);
    $password = sha1($_POST['password']);

    // verificar o utilizador em questão (pretendemos obter uma única linha de registos)
    $login = mysql_query("SELECT userid, username FROM users WHERE username = '$username' AND password = '$password'");

    if ($login && mysql_num_rows($login) == 1) {

        // o utilizador está correctamente validado
        // guardamos as suas informações numa sessão
        $_SESSION['id'] = mysql_result($login, 0, 0);
        $_SESSION['username'] = mysql_result($login, 0, 1);

        echo "<p>Sess&atilde;o iniciada com sucesso como {$_SESSION['username']}</p>";
    } else {

        // falhou o login
        echo "<p>Utilizador ou password invalidos. <a href=\"login.php\">Tente novamente</a></p>";
    }
}
?>

Altura de experimentar. Basta substituir a informação do MySQL de forma correcta, e temos um exemplo funcional de sessões: acedemos à página login.php, e o pedido será enviado para o script processaLogin.php, que nos indicará se as credenciais estão ou não correctas.

Incluir um recurso protegido

Vamos agora ver como incluir uma página que exige autenticação: se o utilizador não tiver sessão iniciada, não pode aceder à página.

verificarLogin.php

<?php
// iniciar uma sessão
session_start();

if (empty($_SESSION['id'])) {

    // não existe sessão iniciada
    // neste caso, levamos o utilizador para a página de login
    header('Location: login.php');
    exit();
}
?>

Tudo o que este pequeno script faz é garantir que a sessão se encontra iniciada e não se encontra vazia. Se a sessão se encontra vazia, então o utilizador é redireccionado, através da função header, para a página de login. Caso a sessão não seja vazia, a função "não faz nada". E porquê?

Este script vai ser incluído em todas as páginas que queremos ver protegidas, ie, exigem autenticação. Iremos usar a instrução requires para carregar o script que verifica se a sessão está ou não activa. Um exemplo:

protegido.php

<?php
// pagina protegida, incluir script de verificação de login
require 'verificarLogin.php';
?>

<h1>P&aacute;gina protegida!</h1>
<p>Ol&aacute; <u><?php echo $_SESSION['username']; ?></u>, esta &eacute; a p&aacute;gina protegida</p>

Reparem que, ao aceder à página protegida (protegido.php), se não tiverem sessão iniciada, é-vos apresentada a página de login. Só após iniciarem sessão podem ver os conteúdos da página protegida no browser.

Terminar sessão

Até aqui vimos como iniciar uma sessão, e garantir que um recurso apenas é acedido se um utilizador estiver com sessão iniciada. Nesta secção, vamos ver como terminar essa sessão de utilizador, deixando este de poder aceder à página protegida até fazer login novamente. Alteremos a nossa página protegida para incluir uma ligação de logout:

protegido.php

<?php
// pagina protegida, incluir script de verificação de login
require 'verificarLogin.php';
?>

<h1>P&aacute;gina protegida!</h1>
<p>Ol&aacute; <u><?php echo $_SESSION['username']; ?></u>, esta &eacute; a p&aacute;gina protegida</p>
<p><a href="logout.php">Terminar sess&atilde;o</a></p>

E criemos uma página para logout:

logout.php

<?php
// aceder às sessões
session_start();

// para terminar uma sessão, apenas é necessário destruí-la
session_destroy();

// redirecionar o utilizador para outra página, login.php por exemplo
header('Location: login.php');
?>

Para experimentar, tentem iniciar sessão, em login.php, e aceder à página protegida (protegido.php). Cliquem na ligação de terminar sessão, e tentem novamente aceder à página protegida. Irão notar que já não conseguem aceder (são novamente reenviados para a página de login), a não ser que efectuem novamente o login.