Installation:
composer require damienharper/user-bundle
Add to config/bundles.php:
return [
// ...
DamienHarper\UserBundle\DamienHarperUserBundle::class => ['all' => true],
];
Publish Configuration:
php artisan vendor:publish --provider="DamienHarper\UserBundle\DamienHarperUserBundle" --tag="config"
This generates config/user_bundle.php. Review and customize:
user_class (default: App\Entity\User)firewall_name (default: main)account_locking settingspassword_expiration settingsCreate User Entity:
Extend DamienHarper\UserBundle\Entity\User or implement DamienHarper\UserBundle\Model\UserInterface:
namespace App\Entity;
use DamienHarper\UserBundle\Entity\User as BaseUser;
class User extends BaseUser {}
Configure Security:
Update config/packages/security.yaml:
security:
providers:
user_provider:
id: DamienHarper\UserBundle\Security\User\DoctrineUserProvider
firewalls:
main:
provider: user_provider
# ... other firewall config
Run Migrations:
php artisan doctrine:migrations:diff
php artisan doctrine:migrations:migrate
Use the built-in login form or create a custom controller:
use Symfony\Component\HttpFoundation\Request;
use DamienHarper\UserBundle\Security\Authentication\AuthenticationUtils;
class LoginController extends AbstractController
{
public function login(Request $request, AuthenticationUtils $authenticationUtils)
{
if ($authenticationUtils->getLastAuthenticationError()) {
// Handle error
}
return $this->render('security/login.html.twig', [
'last_username' => $authenticationUtils->getLastUsername(),
'error' => $authenticationUtils->getLastAuthenticationError(),
]);
}
}
Leverage the UserManager service:
use DamienHarper\UserBundle\Manager\UserManagerInterface;
class RegistrationController
{
public function register(Request $request, UserManagerInterface $userManager)
{
$user = $userManager->createUser();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$userManager->updateUser($user);
// Redirect or flash success
}
}
}
Use the PasswordResetManager:
use DamienHarper\UserBundle\Manager\PasswordResetManagerInterface;
class PasswordResetController
{
public function requestReset(
Request $request,
PasswordResetManagerInterface $passwordResetManager
) {
$form = $this->createForm(PasswordResetRequestType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$passwordResetManager->requestReset($email);
// Notify user
}
}
}
Configure in config/user_bundle.php:
account_locking:
enabled: true
max_attempts: 5
lock_time: 3600 # 1 hour
Check lock status in controllers:
$user = $this->getUser();
if ($user->isAccountLocked()) {
// Handle locked account
}
Configure in config/user_bundle.php:
password_expiration:
enabled: true
days_before_expiration: 30
days_after_expiration: 7
Force password reset on login:
force_password_reset:
enabled: true
first_login_only: true
Extend the User entity:
use DamienHarper\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
class User extends BaseUser
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $customField;
}
Listen to user events (e.g., UserEvents::PASSWORD_RESET):
use DamienHarper\UserBundle\Event\UserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomUserSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
UserEvents::PASSWORD_RESET => 'onPasswordReset',
];
}
public function onPasswordReset(PasswordResetEvent $event)
{
// Custom logic
}
}
Access user data in templates:
{{ app.user.isAccountLocked() ? 'Account locked' : 'Active' }}
{{ app.user.getPasswordExpirationDate() }}
Use the UserManager for API endpoints:
use DamienHarper\UserBundle\Manager\UserManagerInterface;
class UserApiController
{
public function updateProfile(
Request $request,
UserManagerInterface $userManager
) {
$user = $this->getUser();
$data = json_decode($request->getContent(), true);
$user->setFirstName($data['first_name']);
$user->setLastName($data['last_name']);
$userManager->updateUser($user);
}
}
Doctrine Dependency:
DoctrineUserProvider to work with your ORM.Configuration Overrides:
config/user_bundle.php must be done after publishing the config. Forgetting this step leads to default values being ignored.php artisan config:clear after changes to ensure updates take effect.User Entity Naming:
User entity by default. Renaming it requires updating:
config/user_bundle.php (user_class).UserNotFoundException.Password Hashing:
UserPasswordHasherInterface. If you override the hasher, ensure compatibility with the bundle’s UserManager.Account Locking Race Conditions:
User entity.First Login Password Reset:
force_password_reset with first_login_only: true requires checking the isFirstLogin() method, which may not persist across sessions.first_login flag in the user entity and clear it after the first password reset.Authentication Errors:
AuthenticationUtils for errors:
$error = $authenticationUtils->getLastAuthenticationError();
// Error codes: 'invalid_credentials', 'account_locked', 'expired_password'
Event Debugging:
config/packages/dev/monolog.yaml:
handlers:
main:
type: stream
level: debug
channels: ['!event']
Database Issues:
user table with columns like failed_attempts, locked_at, password_expired_at.php artisan doctrine:schema:validate to check schema consistency.Configuration Validation:
php artisan config:dump
user_bundle settings are loaded correctly.Custom User Provider:
UserProviderInterface for non-Doctrine setups:
use DamienHarper\UserBundle\Model\UserProviderInterface;
class CustomUserProvider implements UserProviderInterface
{
public function loadUserByUsername($username) { ... }
public function refreshUser(UserInterface $user) { ... }
public function supportsClass($class) { ... }
}
security.yaml:
providers:
custom_user_provider:
id: App\Security\CustomUserProvider
Custom Password Reset Token:
PasswordResetToken entity or override the PasswordResetManager:
use DamienHarper\UserBundle\Manager\PasswordResetManagerInterface;
class CustomPasswordResetManager implements PasswordResetManagerInterface
{
public function requestReset
How can I help you explore Laravel packages today?