User entity and roles

The (almost) only thing you need to know is that you want a User entity that implements the UserInterface from Symfony security component. That gives you some mandatory fields: email (or username), password, roles...and that's pretty much it. 3 doctrine fields. You can add the name later on if you wish or add it right now. You probably want to add a plainPassword field to help you out manipulating forms, but you certainly don’t want it persisted !

Once your entity is set, let’s go for the configuration ! Our project is in 3.4, but the whole process is very similar in Symfony 4, I will try to update this guide but mainly this follows the Security section from the Symfony docs.

The security.yml file

Following the documentation, you will have to define an encoder, a provider, a firewall and eventually some simple access_control rules like allowing anonymous users to reset their password. Some routes and controllers will be necessary to create, we will come to that just afterwards.

The login process

Once you have configured your firewall with the basic settings, you need to create some controllers and routes. You need a SecurityController where you will have your login(AuthenticationUtils $authenticationUtils) action returning your login template, which again is simply a form following certain naming conventions, the rest being handled by Symfony. A small template will be needed for your form to be usable.

The registration process

This time, Symfony does not really have your back as much as for the login process, but don’t worry all the tools are still there. You will need a RegistrationController with a register() action, and a RegistrationType with the basic fields for your user, keeping in mind you will use the plainPasword field defined in your entity with a RepeatedType form field.

Once your form is ready, your basic {{ form(form) }} template is done, and your submission is valid, several tools will help you finish things up:

UserPasswordEncoderInterface : this will encode the plainPassword into a securely storable hashed password.

That’s actually all you need. But it is very common to log the user in after registration so we will use theses:

TokenStorageInterface : this is used to create a fresh new UsernamePasswordToken and store it.

: this is used to create a fresh new and store it. SessionInterface : this is just to ensure you can store the _security_main serialized session key

And boom your user is now logged in.

Forgot your password ? We got you covered

Once you’ve done the registration process, this one is pretty easy and straightforward. The main difficulty here is that you will need to have emails enabled, an email template or simple message, and a new field in your User entity: passwordResetToken . Then your new ResettingController will have 2 actions: one for asking a reset token sent by email, and another to handle the actual password resetting with a new one. Your token will have to be set to null after successful usage to ensure it's a one shot token.

You can of course imagine more complex logic with an expiry date for the token, but let's keep things simple for a starter pack. Simple hack: create a secure token with bin2hex(random_bytes(32)) on-the-fly. Your new password will be created using a simple ReaptedType form and encoded like in your registration controller, and then you can - again - log in your user during the process, to keep everything smooth.

User roles

I won’t go into much details on this topic as it simply is a CRUD operation.