问题描述
为了让用户在我的系统中注册,我会发送一封带有生成链接的确认邮件.单击时,系统应将 active 属性设置为 true.
For a user to register with my system, I'm sending a confirmation mail with a generated link. On click the system should set an active property to true.
为了创建确认链接,我生成了一个 md5 散列 random_byte 值.这个值是我发送给用户的链接的一部分.该值使用 passwordEncoder 散列并存储在我的数据库中.
To create the confirm link, I generate a md5 hashed random_byte value. This value is part of the link I send to the user. The value is hashed with the passwordEncoder and stored in my database.
当用户单击链接时,系统会根据我的数据库中的哈希值检查该值,并应返回 true,以完全激活用户.由于某种原因验证失败.
When the user clicks the link, the system checks the value against the hash in my database and should return true, to fully activate the user. For some reason the verification fails.
我检查过,在 register() 中生成的 $identifier 值是发送给用户的.他们匹配.所以没有错.
I checked, that the generated $identifier value in register() is the one that gets send to the user. They match. So no mistake there.
起初我只想使用 password_verify(),但也没有成功.
At first I wanted to use password_verify() only, but that didn't work out either.
我只是不知道为什么它不起作用.我最后的猜测是,有一些我不知道的 Symfony 黑暗魔法正在发生.
I simply have no clue, why it's not working. My last guess is, that there is some Symfony dark magic going on, that I'm not aware of.
public function register(EntityManagerInterface $entityManager, Request $request, UserPasswordEncoderInterface $passwordEncoder, MailerInterface $mailer)
{
// Register-Form
$form = $this->createForm(RegisterFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var User $user */
$user = $form->getData();
$user->setPassword($passwordEncoder->encodePassword(
$user,
$form['plainPassword']->getData()
));
// create activation hash
$identifier = md5(random_bytes(16));
$user->setActiveHash(
$passwordEncoder->encodePassword(
$user,
$identifier
)
);
// send activation mail with activation hash
$message = (new TemplatedEmail())
->subject('...')
->from('...')
->to($user->getEmail())
->textTemplate('emails/registration.txt.twig')
->context([
'mail' => $user->getEmail(),
'identifier' => $identifier,
])
;
$mailer->send($message);
// persist & flush
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', '...');
//return $this->redirectToRoute('login');
return $this->render('home/index.html.twig');
}
return $this->render('security/register.html.twig', [
'registerForm' => $form->createView()
]);
}
/**
* @Route("/confirm/{email}/{identifier}", name="register.confirm")
*/
public function confirm($email, $identifier, EntityManagerInterface $entityManager, UserPasswordEncoderInterface $passwordEncoder)
{
$user = $entityManager->getRepository(User::class)->findOneBy([
'email' => $email,
'active' => false
]);
if (!$user) {
// fail no user with email
die('no such user');
}
if( !$passwordEncoder->isPasswordValid($user, $identifier) ){
// Hash verification failed
die('hash failed');
}
$user->setActive(true);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', '...');
return $this->redirectToRoute('login');
}
我尝试使用 password_hash('a_string', PASSWORD_ARGON2ID)
手动散列一个字符串,它抛出一个异常,即 PASSWORD_ARGON2ID 是一个未定义的常量.PASSWORD_ARGON2I 有效.Symfony 以某种方式使用 Argon2ID 作为我的密码字符串,而通过 encodePassword() 生成的 activeHash 字符串以$argon2id..."开头,这怎么可能?
I tried manually hashing a string with password_hash('a_string', PASSWORD_ARGON2ID)
and it throws an exception that PASSWORD_ARGON2ID is an undefined constant. PASSWORD_ARGON2I works. And Symfony somehow uses Argon2ID as my password strings and the activeHash strings generated through encodePassword() start with "$argon2id..." How is that possible?
推荐答案
好的.所以我在本地通过 MAMP 运行 PHP 7.2.正如 msg 在评论中提到的(在它被删除之前),Argon2ID 散列可能是由钠提供的.另一方面,7.2 password_verify() 无法验证 argon2id 哈希.
Ok. So I was running PHP 7.2 via MAMP locally. As (before it was deleted) mentioned in the comments by msg, Argon2ID hashing was probably provided by Sodium. 7.2 password_verify() on the other hand was not able to verify a argon2id hash.
升级到 PHP 7.3.7 没有问题了.
Upgraded to PHP 7.3.7 and no problem anymore.
这篇关于passwordEncoder 生成的用于非身份验证目的的哈希在验证时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!