Problem with login system - array

Asked

Viewed 288 times

2

Hello. I am creating a login system for study purposes.

I identified in the file that is not populating the array with the database information... and yes, I have already made sure that the email and password informed already exists in the database.

Follow login.php file:

<?php

require_once 'init.php';

// resgata dados digitados no formulario
$email = isset($_POST['email']) ? $_POST['email']: '';
$senha = isset($_POST['senha']) ? $_POST['senha']: '';
// Cria o hash da senha
$seg_senha = password_hash($senha, PASSWORD_DEFAULT);

// Verifica se os campos do form nao estao vazios
if(empty($email) || empty($senha)){
    echo 'Informe Email e Senha';
    exit;
}

// Comando no banco de dados
$pdo = db_connect();    // Abre conexão com o banco

$sql = "SELECT id, nome FROM usuarios WHERE email = :email AND senha = :senha";
// Cria query

$stmt = $pdo->prepare($sql);    // Prepare da query

$stmt->bindParam(':email', $email);
// Atribui valor do campo email no valor email da query
$stmt->bindParam(':senha', $seg_senha);
// Atribui valor do campo senha no valor senha da query

$stmt->execute();   // Execute na query

$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);   // Cria array associativo

if(count($arr) <= 0){   // Verifica se existe elemento no array
    echo "<script language='javascript' type='text/javascript'>alert('Login e/ou senha incorretos');window.location.href='../login.php';</script>";
    exit;
}

// Pega o primeiro usuario
$user = $arr[0];

// Inicia a sessão
session_start();
$_SESSION['logged_in'] = true;
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['nome'];

header('Location: ../index1.php');

If I comment from the line if(count($arr) <= 0){ down, and put a var_dump($arr);below $arr = $stmt->fetchAll(PDO::FETCH_ASSOC); returns an empty array

C:\wamp64\www\ProjetoALPHA\core\login.php:33:
array (size=0)
  empty

Could someone help me?

Grateful!

  • 1

    Do not change the question answered, but invalidate the answer. Below are two different snippets, one to detect wrong password separated from wrong user, which is best for you to test. The other section is to warn of the wrong login, better for the day to day. You can not mix the two, or use one or use the other. The negation is to reverse the test result, so you have to use according to what is inside the if and Else. When in doubt, use as you are, and only adjust after you understand.

  • Last time, when I answered you, you had pasted a code in Pastebin that I already pointed out the errors and fixed, the problem was that you had mixed things up. We’re here to help, but if you can keep up with the explanations, it’s easier. As for having withdrawn the acceptance, if that’s why the code did not meet, right you, but it is something that discourages us to help here, because if it did not work after all the time I spent with you, great chance that you did not pay attention to what was explained. 'Cause I only left after you confirmed it was okay.

  • So, if you have something concrete that you can pass, which did not work in the code below, you can even add at the end of your question, or even ask in the comments. but without changing the part that was answered already, otherwise it becomes a mess. And it is no use to fill up with screenshots, because it only complicates the post. If you have to code, format as code (and without removing the original, otherwise it spoils what has been answered and explained).

  • @Bacco, I did not mix the if conditions, I simply tried one that passed me, it did not work, so I tried the other that had passed me, since the second was different from the first by the sign of denial. And I took the acceptance, because even with your help the code did not work as it should, when I posted this question and told him that it was ok because I had not done the test trying to log in with the wrong password. And when I tried that today, the system was logging in even with the wrong password.

  • And I didn’t change the question that was asked, so I entered the equal signs ( === ) to separate the original question from the doubt now

  • Try as code snippet instead of screenshot. With stretch is easier for others who are helping too, and if it is extensive already gets scroll. As a screenshot you can’t even copy and paste to test.

  • 1

    Note that this is not my opinion, here is a list of things that the community generally recommends not to do: http://meta.pt.stackoverflow.com/questions/5483/70

  • I understand. But the print codes are the same ones that are already posted here as code snippets...

Show 3 more comments

1 answer

5

This here will not practically generate the same hash that was written in DB:

$seg_senha = password_hash($senha, PASSWORD_DEFAULT);

and, among other things, that’s why the function is more secure than hashes simple. In addition to using hashes better, the function generates a salt random each time it is used.

Primitive and insecure password systems were made with this technique being tested in the question, and these are vulnerable to attacks from pre-calculated password tables.

To better understand, see this post:

How to hash passwords securely?

To understand that it doesn’t work, take this test:

echo password_hash( '123456', PASSWORD_DEFAULT)."<br>\n";
echo password_hash( '123456', PASSWORD_DEFAULT)."<br>\n";
echo password_hash( '123456', PASSWORD_DEFAULT)."<br>\n";
echo password_hash( '123456', PASSWORD_DEFAULT)."<br>\n";
echo password_hash( '123456', PASSWORD_DEFAULT)."<br>\n";

Check out on IDEONE.

You noticed that the password is the same, but the hash mute? That’s why generating the hash again while doing the SELECT no use.


Solution to your case:

The correct thing is you recover DB data with that user, and the hash, and only then test in PHP like this:

// ELIMINE ISSO DO LOGIN:
// $seg_senha = password_hash($senha, PASSWORD_DEFAULT);
// O password_hash só deve ser usado ao salvar uma senha, não ao ler.

$pdo = db_connect();
$sql = "SELECT id, nome, senha FROM usuarios WHERE email = :email";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':email', $email); // No caso o bindValue é mais adequado
$stmt->execute();

$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if(count($arr) < 1) {
    ... USUARIO NAO EXISTE ...
} else if( password_verify( $senha, $arr[0]['senha'] ) ) {
    ... BEM VINDO AO SISTEMA ...
} else {
    ... SENHA ERRADA ...
} 

Or if you don’t want to give the tip if it was the user or password that got it wrong, to make attacks harder, change the end to

if( ( count($arr) < 1) || (!password_verify( $senha, $arr[0]['senha'])) ) {
    ... SENHA OU USUÁRIO ERRADO ...
} else {
    ... BEM VINDO ...
} 

In general, that’s it. Adjust for your specific case.

Handbook:

http://php.net/manual/en/function.password-verify.php

  • 1

    Be careful there’s a lot of nonsense on the Internet, if you have any questions ask too. There are people who do a lot of crazy, like MD5() of MD5(), thing with Base64() and other things that only make the situation worse instead of making it safer.

  • Yes, I know this well kk, I believe that for more basic situations the password_hash serves very well

  • 1

    @Gabriel not only for the basics. When used right, he is very robust. There is a question here on the site with a very good answer, which even teaches how to do it in a way that whenever you update the security of PHP, every user who renews password automatically has a better hash. I’ll see if I can find the link and put it here for you

  • 1

    http://answall.com/a/147319/70

  • 1

    Oops, another link that will help me then.. I don’t know much about security yet because I’m still learning PHP, which is the first language I go deeper to learn. But I’m sure these two links will serve me well in learning... Thank you!

Browser other questions tagged

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