I'm trying to use UserPasswordInterface from Symfony with my fixtures. All the information of my fixtures arrives in the database but the passwords are not hashed . I get this error message when I do php bin/console doctrine:fixtures:load : In UserPasswordHasher.php line 41:Expected an instance of Symfony\Component\Security\Core\User\UserInterface" as first argument, but got "App\Entity\User"
I already tried using this topic but I think I didn't understand what to do in my case because I have fixtures:
Expected an instance of "Symfony\Component\Security\Core\User\UserInterface" as first argument
According to the terminal, the problem comes from this line in the fixtures :
$hashedPassword = $this->hasher->hashPassword($user, $users[$u]['password']);
.
So I tried replacing it with :
$hashedPassword = $this->hasher->hashPassword($user, $user->getPassword());
but I get this error : Argument 2 passed to Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher:: hashPassword() must be of the type string, null given, called in /var/www/html/TE ST TECHNIQUE WAYATECH/symfony-API/src/DataFixtures/AppFixtures.php on line 7
Thank you sincerely for your help. I hope my question has been drafted properly . Be indulgent I am a beginner and if you have an idea of the solution please explain it to me. Thank you very much!!!
UserEntity
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* [UniqueEntity('mail')]
* @ORM\Entity(repositoryClass=UserRepository::class)
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Cette valeur est obligatoire")
*/
private $firstName;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Cette valeur est obligatoire")
*/
private $lastName;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Cette valeur est obligatoire")
*/
private $mail;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Cette valeur est obligatoire")
* @Assert\Length(10)
*/
private $telephone;
/**
* @ORM\Column(type="json")
* @Assert\NotBlank(message="Cette valeur est obligatoire")
*/
private $role = [];
/**
* @var string The hashed password
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Cette valeur est obligatoire")
*/
private $password;
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getMail(): ?string
{
return $this->mail;
}
public function setMail(string $mail): self
{
$this->mail = $mail;
return $this;
}
public function getTelephone(): ?string
{
return $this->telephone;
}
public function setTelephone(string $telephone): self
{
$this->telephone = $telephone;
return $this;
}
public function getRole(): ?array
{
return $this->role;
}
public function setRole(array $role): self
{
$this->role = $role;
return $this;
}
/**
* Get the hashed password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set the hashed password
*
* @param string $password The hashed password
*
* @return self
*/
public function setPassword(string $password)
{
$this->password = $password;
return $this;
}
}
AppFixtures
<?php
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
use App\Entity\User;
class AppFixtures extends Fixture
{
public function __construct(UserPasswordHasherInterface $hasher)
{
$this->hasher = $hasher;
}
public function load(ObjectManager $manager): void
{
$faker = Factory::create();
$roles = [
'ROLE_USER',
'ROLE_ADMIN',
];
$users =
[
[
'firstname' => 'Jérémy',
'lastname' => 'Brugi',
'email' => '[email protected]',
'password' => 'jeremy.B84*',
'telephone' => '0651758859',
'role' => 'ROLE_ADMIN',
],
[
'firstname' => 'Victor',
'lastname' => 'Lant',
'email' => '[email protected]',
'password' => 'victor.L84*',
'telephone' => '0578598516',
'role' => 'ROLE_ADMIN',
],
[
'firstname' => 'Laure',
'lastname' => 'Chapert',
'email' => '[email protected]',
'password' => 'laure.C84*',
'telephone' => '0485976524',
'role' => 'ROLE_USER',
],
[
'firstname' => 'Elise',
'lastname' => 'Jérémy',
'email' => '[email protected]',
'password' => 'elise.P84*',
'telephone' => '0685741954',
'role' => 'ROLE_USER',
],
];
$userObjects = [];
for ($u = 0; $u <= count($users) - 1; $u ) {
$user = new User;
$user->setFirstName($users[$u]['firstname']);
$user->setLastName($users[$u]['lastname']);
$user->setTelephone($users[$u]['telephone']);
$user->setMail($users[$u]['email']);
$user->setRole([$users[$u]['role']]);
$hashedPassword = $this->hasher->hashPassword($user, $users[$u]['password']);
$user->setPassword($hashedPassword);
$userObjects[] = $user;
$manager->persist($user);
}
$manager->flush();
}
}
security.yaml
security:
enable_authenticator_manager: true
encoders:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: "auto"
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
CodePudding user response:
Welcome to Stack Overflow :)
The first error tells that your User class has to implement the UserInterface
interface. I think reading the symfony docs as to how implementing a user works would be a good starting point :) If you have any more questions, please let me know.
PS. Your first post looks good!
/**
* [UniqueEntity('mail')]
* @ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
//...
}