2017-02-19 4 views
-1

Это, как я установил свой пароль:Hashed пароль и createQueryBuilder()

$member->setPassword(password_hash($_POST['pw1'], PASSWORD_DEFAULT)); 

Чтобы проверить, если пароль правильный, я могу просто использовать этот код:

if(password_verify($password, $hashed_pw)) { // $hashed_pw is not set, since this is just an example 
    // Do something here 
} 

До сих пор все хорошо.

Проблема

Я строй запроса с помощью этого метода:

private function getData($username, $password) { 
    // Getting the data 
    $query = $this->getDoctrine()->getRepository('AppBundle:Members') 
     ->createQueryBuilder('t') 
     ->where('t.email = :email') 
     ->andWhere('t.password = :password') 
     ->setParameter('email', $username) 
     ->setParameter('password', $password) 
     ->getQuery(); 
    $result = $query->getResult(); 

    // Get the name 
    $name = $result[0]->getName(); 

    // Check if query exists 
    $result = ($result) ? $name : false; 
    return $result; 
} 

Все будет просто отлично работает, если пароль не хэшированное. Ну, в моем случае пароли хэшированы, и я понятия не имею, как я могу это преодолеть.

Я полностью смущен, любая помощь будет очень признательна!

+0

Как вы используете Symfony, рассмотрели ли вы использование инструментов, предоставляемых каркасом? https://symfony.com/doc/current/security/entity_provider.html – lxg

ответ

1

Вот мой ответ:

private function verifyUser($username, $password) { 
    $em = $this->getDoctrine()->getManager(); 
    $qb = $em->createQueryBuilder(); 
    $qb->select('m') 
     ->from('AppBundle:Members', 'm') 
     ->where('m.email = :email') 
     ->andWhere('m.password = :password') 
     ->setParameter('email', $username) 
     ->setParameter('password', $password) 
    ; 
    $member = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult(); 

    if($member == null) { 
     $result = null; 
    } 
    else{ 
     $result = $member->getName(); 
    } 

    return $result; 
} 

Объяснение: Переименован вашу функцию verifyUser, так это то, что он делает . Как вы увидите, я сделал код так, чтобы, когда разработчик его читает, он должен иметь смысл, и будет легче поддерживать, если вам придется изменить код в будущем.

Я получаю EntityManager и создаю QueryBuilder, а затем создаю запрос, который задает пароль электронной почты &. Обратите внимание, что я звоню getOneOrNullResult, что важно. Если вы не получили результат (null), то пароль, который был передан, не соответствует тому, что хранится, и это не пользователь.

Я также установил setMaxResults к , который должен возвращать только результат (если он соответствует), так как вы должны иметь только один пользователь с этим паролем (надеюсь, что и в случае с вашим дизайном, если нет - вам нужно переосмыслить дизайн).

Затем я проверяю, чтобы увидеть $member, который является одним из членов или null, если он не соответствует, и установите $result для возврата соответственно.

Я использовал null в качестве возвращаемого значения вместо false, поскольку false является boolean, и это лучше дизайн вернуться null в этом случае.

Надеюсь, что все имеет смысл.


EDIT # 2 - включение хэш пароля

private function verifyUser($username, $password) { 
    $em = $this->getDoctrine()->getManager(); 
    $qb = $em->createQueryBuilder(); 
    $qb->select('m') 
     ->from('AppBundle:Members', 'm') 
     ->where('m.email = :email') 
     ->setParameter('email', $username) 
    ; 
    $member = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult(); 

    if(password_verify($password, $member->getPasswordHash())){ 
     $result = $member->getName(); 
    } 
    else{ 
     $result = null; 
    } 

    return $result; 
} 

выше метод предполагает, что вы хранить хэш пароля в вас Entity член, то вы получите его с помощью функции getPasswordHash().

+0

Большое вам спасибо за то, что вы тратите свое время и публикуете этот ответ. Ваш код выглядит определенно намного чище, чем мой, но, честно говоря, я не очень уверен, что мы оба получим тот же результат, если вы сравните свой ответ с моим. Обратите внимание, что 'password_verify()' не является моей собственной функцией. Это существующая функция PHP (http://php.net/manual/en/function.password-verify.php) и в основном суть моей проблемы. –

+0

Да, я знаю эту функцию, но вы не используете ее правильно в своем коде и, таким образом, мой ответ. Его нужно вызывать вне функции 'verifyUser', а затем передать пароль' $ password', если он совпадает. –

+0

Значит, у меня будет две функции? Первым будет 'verifyUser()', который вернет либо '$ member-> getName()', либо 'null', а второй, вероятно, будет называться' getPassword() ', который просто вернет хешированный пароль. И тогда я могу использовать 'password_verify()' вне обеих функций, правильно? Если это так, мне все равно понадобятся два запроса, но не в одной и той же функции. Или я ошибаюсь? –

0

Ничего, я просто отвечаю на свой вопрос. Мне просто нужно, чтобы создать еще один запрос:

private function getData($username, $password) { 

    // Get the PW 
    $query_pw = $this->getDoctrine()->getRepository('AppBundle:Members') 
     ->createQueryBuilder('m') 
     ->where('m.email = :email') 
     ->setParameter('email', $username) 
     ->getQuery(); 
    $result_pw = $query_pw->getResult(); 

    if ($result_pw) { 
     $hashed_pw = $result_pw[0]->getPassword(); 
    } 
    else { 
     $hashed_pw = false; 
    } 

    // Getting the data 
    $query = $this->getDoctrine()->getRepository('AppBundle:Members') 
     ->createQueryBuilder('t') 
     ->where('t.email = :email') 
     ->andWhere('t.password = :password') 
     ->setParameter('email', $username) 
     ->setParameter('password', $hashed_pw) 
     ->getQuery(); 
    $result = $query->getResult(); 

    // Verify the password 
    if(password_verify($password, $hashed_pw)) { 
     // Get the name 
     $name = $result[0]->getName(); 
    } 
    else { 
     $name = false; 
    } 

    // Check if query exists 
    $result = ($result) ? $name : false; 
    return $result; 
} 
+1

И дело в том, что? – Cerad

+1

Предлагаем вам проголосовать, чтобы закрыть @Cerad, поскольку это очень плохо написанный пост, а также плохо написанный код. –

+0

@AlvinBunk Если все плохо написанные сообщения/код были закрыты, то не осталось бы много. И мне интересно узнать причины этих двух запросов. – Cerad

Смежные вопросы