Login system with PHP

Asked

Viewed 1,793 times

2

Hello, I need to do an administrative area, and obviously I need a login and password system. I know that there are already questions on this subject, but I fear that they are outdated. I want a way as simple and safe as possible. I also do not want anyone to do anything for me, even because I am learning and obviously want to master it, I just want to be given tips on how to do, reference links and etc. Thank you from now.

What I have so far:

<form action="submit" method="POST">
    <h1>LOGIN:</h1>
    <input type="text" name="login">
    <h1>SENHA:</h1>
    <input type="password" name="password">
    <button type="submit">ENTRAR</button>
</form>
  • Besides html it is interesting to post some code some attempt as you did and Talz for the staff to give the tips beyond that

  • Who voted as too broad could comment on the reason for this.

  • Tiago, Unfortunately this question is too broad for a direct answer and not based on opinions, it would be interesting if you had a specific question in this issue of logging in with php. If you don’t know where to start google can help you with this, look at an example: http://www.linhadecodigo.com.br/artigo/3561/criando-um-system-de-register-e-login-com-php-e-mysql.aspx

  • I didn’t vote, but she’s too broad anyway!

  • I don’t think it’s too wide because I didn’t ask for any concrete answers, I didn’t ask them to do any code for me, I just asked for tips on where to start studying. @Gabrielrodrigues

  • I did not vote but there are many ways to do, characterizing too broad. If you put some code like I’m going this way it would be easier because it would already have a way. now the way you put it was like do it for me in the best way possible.

  • There are answers to my questions in this context of login, see these questions they are login but they are very different answers: http://answall.com/questions/70758/acesso-somente-via-login-e-senha-inhibitor-directaccession-via-url/70765#70765 http://en.stackoverflow.com/questions/95352/login-with-cookie-or-Session-no-php5/95358#95358

  • No, @Otto I don’t want you to do it for me, on the contrary, I’m sorry if it seemed that way, but I want the exact opposite, I just want you to steer me down some path where I can do and learn as best I can.

  • I think the question is good, especially in light of some answers, but this has been asked before. If you think Sei que já existem aqui, perguntas sobre este assunto, mas temo que elas estejam desatualizadas needs to explain and demonstrate why.

  • The only problem with these answers is that they always take those who are learning PHP to the procedural paradigm side. Most do not know how to work organized with it and create great works of art with their codes, so the bad reputation of language.

Show 6 more comments

5 answers

6

Something I see a lot in the tutorials I find on the internet is that they separate the configuration of the presentation but do not use as we see in most of the sites that people create nowadays, they simply separate these files through directories, then you can program without using and make the site simple.

\- root
 + - configuracao
    - includes
    - conexão
 + site
    - css
    - imagens
    - javascript
    - index.php
    - login.php
    + administração
      - css
      - imagens
      - javascript
      - index.php
      - login.php
      - apagar.php
      - cadastrar.php

You could opt for a similar structure and make your application simple and safe. Separating administrator login from normal user logins, and also separating user tables from administrators in the database.

You must restrict the privileges for users of these tables, sanitize the data before it is recorded in the database, and also the data that users and administrators enter to log in to the system or change data in the database.

You can use these functions of hash to encrypt passwords before writing to the database.

If you want more tips, there are also these posts here:

How to hash passwords securely?

What is the best way to create a PHP login system

Safely remember user

  • Thank you very much, I will study and I found your recommendations great. :)

6


Forget SHA1 and MD5

Before you start, make it clear. Do not use any of these encryption methods. You will understand why in the course of this answer.

Important information

I recommend you read this reply, then read that Article by Thiago Belem, then that PHP documentation article itself.

The above links will show why you should not use sha1 or MD5.

In the case of the second link I passed, not only read, but run what was taught and run again until you know what is being done. After that, I recommend that also the process using the instructions of the third link, the password_hash

I won’t reinvent the wheel here, because the first link already has everything you need to know and the rest are the encryption exercises.

I’ll give you an example of a solution for your case, simple and commented so you understand. In the example I will use the password_hash, which is the safest method currently.

Example of use

In HTML

<form action="" method="post">
    <label for="login">Login</label>
    <input type="text" name="login" id="login">
    <label for="senha">Senha</label>
    <input type="password" name="password" id="password">
    <button type="submit">Fazer login</button>
    <input type="hidden" name="hidden" <?php echo "value='" . $_SESSION['formKey'] . "'" ?>>
</form>

In the action do not need to put anything, since we will use the same page of the form to validate the data.

If you read the first link I gave you, you should know that the type input field hidden serves to hinder ataques do tipo CSRF (Cross-site Request Forgery), where the form will only be validated if the value of the hidden is equal to the value of $_SESSION['formKey']. Remembering that this $_SESSION should be amended each time the page is updated, after the method has been validated $_POST, of course. In PHP code you will understand.

I recommend you read that article on CSRF attacks.

The Abels issue is just one aspect of UX design, where you allow the user to click the label, and focus on input.

In PHP

<?php

    //Possibilita que trabalhemos com sessões, vai ser útil para validar o campo
    //hidden, e também para manter o usuário logado no sistema.
    //mas isso é outro ponto e não vou abordá-lo aqui.
    session_start();

    //Dados do banco
    $hostname = 'localhost';
    $username = 'root';
    $password = '123456';
    $database = 'meusite';

    //Se conecta ao banco de dados
    $mysql = mysqli_connect($hostname, $username, $password, $database);
    mysqli_set_charset($mysql, 'utf8');

    //Se o usuário clicar em submit, ele faz uma requisição POST e aciona
    //essa condição
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        //Verifica se o valor do campo hidden bate com o valor da session.
        if (isset($_POST['hidden']) && $_POST['hidden'] == $_SESSION['formKey']) {

            //Verifica se existe um POST chamado login e senha respectivamente e,
            //se existir, remove os espaços no começo e final da string usando a função
            //trim() e atribui o valor deles as respectivas variáveis.
            //Se não existir, define o valor da variável como null.

            //Se não entendeu como funciona, pesquise sobre OPERADOR TERNÁRIO e função TRIM
            $login      = (isset($_POST['login'])) ? trim($_POST['login']) : null;
            $password   = (isset($_POST['password'])) ? trim($_POST['password']) : null;

            if (empty($login)) {
                //Se a variável $login estiver vazia, faça:
                echo 'Por favor, preencha o campo de login';
                exit;
            }
            if (empty($password)) {
                //Se a variável $password estiver vazia, faça:
                echo 'Por favor, preencha o campo de senha';
                exit;
            }

            //Antes de comparar qualquer dado com o banco, fazemos escape para dificultar
            //SQL injections.
            $login      = mysqli_real_escape_string($mysql, $login);
            $password   = mysqli_real_escape_string($mysql, $password);

            //Seleciona os campos login e password na tabela usuarios, cujo login seja
            //igual ao login informado no formulário.
            //Lembre-se de marcar a coluna login no banco de dados como UNIQUE ID
            //para que não seja possível existir mais de um login igual.
            $result = mysqli_query($mysql,
            "SELECT `login`, `password` FROM `usuarios` WHERE `login` = '" . $login . "'");

            if(!mysqli_num_rows($result)) {
                echo "Usuário não encontrado";
                exit;
            } else {
                //Coloca os dados retornados pelo banco em um array chamado $data
                while ($r = mysqli_fetch_assoc($result)) {
                    $data[] = $r;
                }
            }

            //Chegando neste ponto, entede-se que o login informado existe, agora temos que
            //validar a senha.

            //Vamos supor que você usou password_hash para criptografar a senha no
            //momento do cadastro do usuário.

            if (password_verify($password, $data[0]['password'])) {
                echo "Logado com sucesso!";
            } else {
                echo "Senha incorreta!";
                exit;
            }

            //Fazendo isso, estamos dizendo pro PHP verificar se a senha informada
            //corresponde ao hash (senha criptografada) que estava no banco.
        }
    }

    //Toda vez que ele atualizar a página, o value do campo hidden será alterado
    //Abaixo fizemos o sha1 de um número randomico usando a função rand().
    $_SESSION['formKey'] = sha1(rand());

    //Eu usei sha1, porque? Simples. O valor do campo hidden não tem importancia
    //pra gente. Ele não precisa ser seguro, até porque ele será visível caso
    //o usuário clique em visualiar o código fonte, ele só precisa mudar e ser
    //impossível de se acertar num "chute".
?>

The cake recipe is there, just use it.

  • Too professional the answer ++1!

  • 1

    @Claydersonferreira, use mysqli_real_escape_string() with mysqli_* is no longer necessary, besides you are passing variable directly in SQL, which is not very safe. See here the solutions that exist within the mysqli_*.

  • On the Mysql website have another example

  • Really, really good this method you gave me. Thanks for the tip :)

2

Take a look at this blog: login - OO. An object-oriented example using PHP. For password use SHA1: Passwords

  • Thank you very much! I will look yes!! :)

2

I recommend studying also in MD5 (or SHA1 as our friend @Bia mentioned). Also look over Login Validation by Sessions. And if you want, take a look at SQL Inject to learn a little more about the security holes that STILL exist on many websites. Good studies!

PS: a similar topic already exists: Best way to make a login and password system with PHP

  • Thank you so much for the tips!! I will study all this. Thanks friend :)

1

Briefly: As you are starting now, the first step I can suggest to study, before making a login and password system, is to follow the normalization of Psrs, After all, we don’t want any more bad code out there.

The second step is, whenever possible, to consult the Official Documentation of PHP.

This site has plenty of information for those who need to learn how to develop with PHP.

To make a login system, you will basically need to:

  1. Connection to a database
  2. Session setting
  3. Create user, password and hash

For pages that you have access restriction, you must create access levels for users, one way to do this is giving weight to the user, in the example below, I will give 3 weights, 0 - blocked, 1 - editor, 2 - administrator.

User table:

CREATE TABLE `User` (
  `id_user` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  `password` varchar(255) NOT NULL,
  `createdAt` TIMESTAMP NOT NULL DEFAULT current_timestamp,
  `salt` varchar(255) NOT NULL,
  PRIMARY KEY (`id_user`),
  KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Dados do Usuário';

Table of the user profile:

  CREATE TABLE `Roles` (
  `id_role` int(11) NOT NULL AUTO_INCREMENT,
  `fk_user` int(11) NOT NULL,
  `level` int(9) NOT NULL DEFAULT '0',
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`id_role`),
  KEY `fk_Roles_1_idx` (`fk_user`),
  CONSTRAINT `fk_Roles_1` FOREIGN KEY (`fk_user`) REFERENCES `User` (`id_user`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Níveis de acesso do Usuário';

Now, to check the access levels, you would make a query of this type, catching all users who are not locked (0):

function createPassword($pass)
{
 //salve isso no User.password 
  return password_hash($pass, PASSWORD_DEFAULT);
}

function checkLogin($user, $pass, $dbh)
{

$sth = $dbh->prepare("SELECT Users.password as pass_hash AND Users.username :=user");
$sth->bindParam(':user', $user, PDO::PARAM_STR);
$sth->execute();
$resultHash = $sth->fetch(PDO::FETCH_OBJ);
if (validPassword($pass, $resultHash->pass_hash)) {

   $sth = $dbh->prepare("SELECT  Users.id_user as 'ID',
                                 Users.username,
                                 Roles.name,
                                 Roles.level
                         FROM    Users
                         INNER JOIN Roles ON
                                 (User.id_user=Roles.fk_user
                                  AND  Roles.level != 0)
                         WHERE   Users.username :=user
                      ");
   $sth->bindParam(':user', $user, PDO::PARAM_STR);
   $sth->execute();
   $result = $sth->fetch(PDO::FETCH_OBJ);
   createSession($result);
 }
}

function validPassword($pass, $hash)
{
  return password_verify($pass, $hash);
}

So basically, you will check the login. And once you confirm, you create the session:

function createSession($dados)
{
    session_start();
    $_SESSION['level_user'] = $dados['level'];
    $_SESSION['ip_user'] = $_SERVER['REMOTE_ADDR'];
    $_SESSION['tipo_user'] = $dados['name'];
    $_SESSION['username'] = $dados['username'];
}

And then check if the user is logged in and the level of it:

 function checkSession($nivel)
 {
    session_start();
    if ($_SESSION['level_user'] == $nivel && $_SESSION['ip_user'] == $_SERVER['REMOTE_DDR'] &&  isset($_SESSION['username'])) {
           //permitido
    } else {
          //não permitido
    }           
 }
  • Great, I will study and also study your answer, thank you very much for your time ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.