Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Model Usuario

Queria sabe como a entidade Usuários conseguiu pegar os parametros da senha e comparar com a criptografada. Fiz todo o curso com o doctrine , porém refiz tudo usando PDO puro para ter uma maior autonomia e tmb entender melhor o que se passa por baixo dos panos. Acontece que pegando alguns códigos do curso de PDO daqui mesmo , consegui criar dois repositorios , um para cursos, outro para usuários.

Chegando nessaparte de validação sofri um pouco para entender que ele nao busca de fato a senha no bando mas usa como SELECT o email, ou usuario , ou qualquer que seja o parametro para buscar o array com a tebela referida. acontece que para fazer essa query usando pdo fiz um metodo dentro do repositorio user que trás essa função porem chamando os parametros de conferencia no proprio metodo --> public function Login($usuario, $senha){}...

Para usar esse método que vc fez com seu user, devo mudar meu metdo para public function login(Usuario $usuario){}... e completar os bind com as instancias?

5 respostas

Denis, têm muitas perguntas dentro de uma, então vamos por partes. rsrsr

Queria sabe como a entidade Usuários conseguiu pegar os parametros da senha e comparar com a criptografada.

Através desse pedaço de código:

public function senhaEstaCorreta(string $senhaPura): bool
{
    return password_verify($senhaPura, $this->senha);
}

Aqui eu comparo o hash com a senha em texto puro recebida pelo usuário.

ele nao busca de fato a senha no bando

Busca sim. O método find do repositório traz uma entidade Usuario completa, ou seja, usuário, senha, etc. :-)

Acho que com essas 2 respostas você já consegue se encontrar, certo? Caso continue com dúvida, só falar. :-)

Veja este exemplo do meu código, considerando que os valores dos atributos estão vindo pelo formulário $_POST devidamente filtrados.

$usuario = filter_input(INPUT_POST , 'usuario', FILTER_SANITIZE_STRING);
$senha= filter_input(INPUT_POST , 'senha', FILTER_SANITIZE_STRING);

$e = new Usuario();
$e->setUsuario($usuario);
$e->setSenha($senha);

$stmt = $pdo->prepare(
    'SELECT * FROM usuarios WHERE usuario = :usuario LIMIT 1'
);
$stmt->bindValue(':usuario', $e->getUsuario());
$stmt->execute();
try {
    if ($stmt->rowCount() < 0) {
        echo 'erro usuario não existe';
        exit();
    } else {
        $usuarioQuery = $stmt->fetch();

        $validate = password_verify($e->getSenha(), $usuarioQuery['senha']);
    }
} catch (Exception $ex) {
    echo 'Erro ao validar senha';
}

A dúvida esta na parte que busco no BD um usuário, e ele retorna este usuário com todos os dados , id, usuario e senha que foram os dados da tabela que fiz. Quando coloco o bindValue para buscar a senha tmb, dá erro e nem entra na condicional que conta as linhas afetadas, pois ao fazer essa busca com a senha pura ela nao bate com a senha criptografada.

Se eu criptografar a senha antes de enviar a buscar pela senha do meu usuário no DB ela retorna false visto que o argon2I não estatiza a senha com os mesmos caracteres,

$usuario = filter_input(INPUT_POST , 'usuario', FILTER_SANITIZE_STRING);
$senha= filter_input(INPUT_POST , 'senha', FILTER_SANITIZE_STRING);

$e = new Usuario();
$e->setUsuario($usuario);
$e->setSenha($senha);
password_hash($senha, PASSWORD_ARGON2I);

$stmt = $pdo->prepare(
    'SELECT * FROM usuarios WHERE usuario = :usuario AND senha = :senha LIMIT 1'
);
$stmt->bindValue(':usuario', $e->getUsuario());
$stmt->bindValue(':usuario', $e->getSenha());
$stmt->execute();
try {
    if ($stmt->rowCount() < 0) {
        echo 'erro usuario não existe';
        exit();
    } else {
        $usuarioQuery = $stmt->fetch();

        $validate = password_verify($e->getSenha(), $usuarioQuery['senha']);
    }
} catch (Exception $ex) {
    echo 'Erro ao validar senha';
}

então essa parte eh assim mesmo fazendo a consulta pelo usuario e no fetch pegando tudo se existir? Porque no primeiro código funciona no segundo não.

Denis, de novo, não sei se to entendendo sua dúvida...

Basicamente: Você recebe no seu controller o usuário e a senha em texto puro. No banco você tem armazenada a senha cifrada, logo, não pode buscar direto no banco pela senha.

Então pra autenticar precisa usar o password_verify pra comparar a senha que você recebeu com o hash no banco.

:-)

Obrigado pela resposta, Vinicius a dúvida é a seguinte, tentarei ser mais conciso. No teu código vc usa o método do doctrine chamado finByOne e você busca a senha usando somente o email como referência nesta parte $usuario = $this->repositorioUsuarios ->findOneBy(['email' => $email]); . EU NÃO estou usando o doctrine logo por ser algo mas à mão e por ser leigo no assunto , só consegui buscar a senha no DB já com HASH através do PDO como postei acima usando igualmente vc fez o email para buscar todos os dados bem como a senha. A pergunta é se é deste modo mesmo usando somente um parametro no caso EMAIL para pegar a senha via fetch? Para então fazer o password_verify?

solução!

Então, Denis. Essa pergunta foi respondida na resposta acima

Você recebe no seu controller o usuário e a senha em texto puro. No banco você tem armazenada a senha cifrada, logo, não pode buscar direto no banco pela senha.

Ou seja, pra buscar do banco de dados, você usa somente o e-mail. Depois de buscar, você verifica, então, se a senha está correta com o password_verify.

Usar Doctrine ou não é um mero detalhe. :-) O processo é idêntico com PDO, MySQLi, Eloquent, o que for. :-D