// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "^3.3", // v3.3.0
"composer/package-versions-deprecated": "^1.11", // 1.11.99.4
"doctrine/annotations": "^1.0", // 1.13.2
"doctrine/doctrine-bundle": "^2.1", // 2.6.3
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.1.1
"doctrine/orm": "^2.7", // 2.10.1
"knplabs/knp-markdown-bundle": "^1.8", // 1.9.0
"knplabs/knp-time-bundle": "^1.11", // v1.16.1
"pagerfanta/doctrine-orm-adapter": "^3.3", // v3.3.0
"pagerfanta/twig": "^3.3", // v3.3.0
"phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
"scheb/2fa-bundle": "^5.12", // v5.12.1
"scheb/2fa-qr-code": "^5.12", // v5.12.1
"scheb/2fa-totp": "^5.12", // v5.12.1
"sensio/framework-extra-bundle": "^6.0", // v6.2.0
"stof/doctrine-extensions-bundle": "^1.4", // v1.6.0
"symfony/asset": "5.3.*", // v5.3.4
"symfony/console": "5.3.*", // v5.3.7
"symfony/dotenv": "5.3.*", // v5.3.8
"symfony/flex": "^1.3.1", // v1.17.5
"symfony/form": "5.3.*", // v5.3.8
"symfony/framework-bundle": "5.3.*", // v5.3.8
"symfony/monolog-bundle": "^3.0", // v3.7.0
"symfony/property-access": "5.3.*", // v5.3.8
"symfony/property-info": "5.3.*", // v5.3.8
"symfony/rate-limiter": "5.3.*", // v5.3.4
"symfony/runtime": "5.3.*", // v5.3.4
"symfony/security-bundle": "5.3.*", // v5.3.8
"symfony/serializer": "5.3.*", // v5.3.8
"symfony/stopwatch": "5.3.*", // v5.3.4
"symfony/twig-bundle": "5.3.*", // v5.3.4
"symfony/ux-chartjs": "^1.3", // v1.3.0
"symfony/validator": "5.3.*", // v5.3.8
"symfony/webpack-encore-bundle": "^1.7", // v1.12.0
"symfony/yaml": "5.3.*", // v5.3.6
"symfonycasts/verify-email-bundle": "^1.5", // v1.5.0
"twig/extra-bundle": "^2.12|^3.0", // v3.3.3
"twig/string-extra": "^3.3", // v3.3.3
"twig/twig": "^2.12|^3.0" // v3.3.3
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.0
"symfony/debug-bundle": "5.3.*", // v5.3.4
"symfony/maker-bundle": "^1.15", // v1.34.0
"symfony/var-dumper": "5.3.*", // v5.3.8
"symfony/web-profiler-bundle": "5.3.*", // v5.3.8
"zenstruck/foundry": "^1.1" // v1.13.3
}
}
It's security time! Symfony 5.3 comes with a reimagined version of its security system and I ❤️it! Yes, it's still super flexible & dependable. But the "guts" have been streamlined and simplified, making it easier to get your job done and giving you readable code if you need to dive into the core.
In this course, we'll go from an introduction into Symfony security into a full-blown application with users, permissions, custom voters and multiple ways to authenticate:
make:user
IS_AUTHENTICATED_FULLY
, IS_AUTHENTICATED_REMEMBERED
, PUBLIC_ACCESS
switch_user
)So let's make:user
& make:auth
our way to... make:profit
... or at least to a great security system!
Hey Sasa,
Thank you for your interest in SymfonyCasts tutorials!
Yeah, that's a good idea! And probably this course will fit this topic well. I'll add this to our topics list about Security in order to cover it in this tutorial, tough I'm not 100% sure if it will be included or no, but we will try our best.
Thanks for this idea! And if you could tell us a bit more what exactly is complex for you in this topic, or where exactly you're stuck, or what isn't covered by the official docs - that would be awesome and helps us to consider if it should be included in this tutorial or maybe deserves its own mini tutorial.
Cheers!
Hi Victor,
Thank you for interesting,
I create my security by watching videos from Symfony cast. And now I have problem to implement server side receptcha. There is some bundles but they use symfony forms for rendering login form, and they use Recaptcha3Type as a custom form type field, but I have basic HTML form, and I am confused. Also I founded bundle https://github.com/google/r..., but I don't know where and how to implement server side code.
Also maybe You can consider to cover integration with Oauth2, I find some instruction for implementing: https://dev.to/_mertsimsek/... - but it is much better when You explains it 😊.
Dont get me wrong, I understand that the goal is to present the possibilities of a security bundle, but for someone who does not have a lot of experience, or just want to make something quick and small in Symfony, everything get litle complicated and it takes too much time.
I think that there should be some simple, fast and reusable solution that will cover everything that is needed for authentication (Registration with email validation, reset pass, Log in, Oauth2, receptcha....)
Also I must say that I am very happy that I am accidentally found reset-password-bundle, and verify-email-bundle, and I think that's the right way to simplify and speed things up for Authentication
Best regard
Hey Sasa!
Thank you for providing more info from your side! It's really helpful when things come to planning a new course :) I won't promise everything your mentioned will be covered in this course, but I'll do my best to deliver this to the course authors, and probably they will fit some topics into it.
Also, good catch on those reset-password-bundle and verify-email-bundle :) Yeah, we would also like to cover them in our future screencasts, those bundles kinda new, and it would help to reveal them to more devs this way.
About oauth, you could also check another our bundle: https://github.com/knpunive... that helps with integration - it also has docs with examples how to configure it in your project.
I hope this helps!
Cheers!
Hey It O.!
This is the *next* tutorial - so it's right after Turbo. My guess would be about 3 weeks - it won't be significantly delayed because it's definitely happening after Turbo (I'm mostly not sure because I don't know yet exactly how long Turbo will go).
So, soon! Cjeers!
Hello,
can i use symfonycasts/verify-email-bundle with Symfony 6.3?
I installed it in a 6.3 project, but files that were generated are quite different to the files here in this tutorial or github or in the symfony documentation.
i can't find where the verify URL is generated and no email is send.
maybe there is another bundle for registration confirmation?
thank you for your help.
JD
Hey @Johann!
Sorry for the slow reply! Yes, it should work just fine, hmm.
but files that were generated are quite different to the files here in this tutorial or github or in the symfony documentation
This is something we will need to check into - I totally see what you're referring to though!
i can't find where the verify URL is generated and no email is send.
When I followed the docs just now, I end up with some code that looks like this:
A) RegistrationController::register()
- inside the if ($form->isSubmitted() && $form->isValid()) {
, I have:
$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
(new TemplatedEmail())
->from(new Address('mailer@example.com', 'AcmeMailBot'))
->to($user->getEmail())
->subject('Please Confirm your Email')
->htmlTemplate('registration/confirmation_email.html.twig')
);
B) In src/Security/EmailVerifier.php
, we generate a new helper class to actually send the confirmation email. Its sendEmailConfirmation()
contains the code that creates the signedUrl
and other variables for confirmation + actually sends the email with $this->mailer->send()
.
Do you see similar code? Does this help point in the right direction? Emails are always tricky because it's possible everything works... but then a misconfiguration in the email system causes the email to not actually be delivered. However, you can always go to /_profiler
and find the POST
request to /register
and click to see the profiler for that page. There, should be able to click the Emails
tab on the left. If an email was sent during the successful registration form submit, you should see it here.
Let me know if that helps!
Cheers!
Hi Ryan,
thanks for the hints. Everything was my bad :-(
for whatever reason i have no debug-toolbar on the 'lost pw request-page'. (i have to investigate this). so i couldn't see the qeued emails because of the forgotten (i forgot) 'Symfony\Component\Mailer\Messenger\SendEmailMessage: async' config. i commented it out, and everything works fine!
thank you
Woo! I'm just happy it worked! And anyway, this poked me to update the verify bundle docs :)
Cheers!
Hello, the database configuration is a pain.
with xampp, when I make:migration I get
` Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB serve
r version for the right syntax to use near 'INDEX idx_9474526c1e27f6bf TO IDX_DADD4A251E27F6BF' at line 1`
then I retry make:migation and I get: Column already exists: 1060 Duplicate column name 'status'
what's going on here ?
Hey Grenouille,
We're using MySQL server in this course but looks like you have MariaDB installed. Though MySQL and MariaDB almost identical, they may have some differences, and looks like one of it you revealed with that error I'd recommend you to use MySQL instead if you have it installed, otherwise, since it's a learning project and does not contain any important data - you can skip migrations and just run:
$ bin/console doctrine:schema:update --force
It will sync the DB schema with your mapping configuration. You may lose some important data in the DB this way, but if those data are dummy data and you don't care about it - that's totally OK. And you can always reload fixtures again if needed.
I hope this helps!
P.S. But if you you'r working on a real project and will try to deploy changes to production - it seems like you need to regenerate migrations for your specific DB version.
Cheers!
Hi,
is there a way to use CustomCredential with hashed password? I thought this could work but apparently, it doesn't:
`
....
new CustomCredentials(function($credentials, User $user) {
return $this->passwordHasher->hashPassword($user, $credentials) === $user->getPassword();
}, $password)`
I'm hashing the given plain password and I'm trying to check the hash using the password hasher.
But it does not work. What is wrong? ( I know I should use PasswordCredential ... )
Yes, only one chapter to go! 🎉🎉🎉 And off course looking forward for new courses! Is there a place on this site where we can follow which courses are being released in the near future? I know the next one will be EasyAdmin. But i'm really curious for the other *top secret* plans that you have.
Hey Lex,
Yeah, it's super closed to be released in full already :) Yeah, we do have such a page! Take a look at this link: https://symfonycasts.com/co... - this will list upcoming tutorials, but nothing much there yet except the EastAdmin that you're right should be next, and it should happen very soon already ;)
Thank you for your patience!
Cheers!
Hey @Solvex
You're right we do not have a dedicated course on cache, but it's because it's just a small thing that we explain in other tutorials. I'll leave you here a chapter that you can watch about caching stuff
https://symfonycasts.com/sc...
Cheers!
I don't think cache is simple. Contracts, PSR-6, Marshalling, CachePoolItem, TagAware... In fact, it is very difficult to use, especially the tagged cache. Perhaps a small course of 5-10 lessons will fill in the gaps when using the cache.
Hey Solvex,
Sure! SymfonyCasts doesn't have any courses that were not finished after they had started releasing ;) It will be continued after Christmas / New Year holidays, sorry for any inconvenience and thanks for your patience!
Cheers!
Thanks!
We have been looking forward to this course for so long!
Merry Christmas and a Happy New Year!
Hey Solvex,
Merry Christmas and a Happy New Year to you too! :) Sorry for holiday delays!
Cheers!
Hello SymfonyCasts team!
Great job you are doing - i like you tutorials.
Could you please add logout after timeout (logout unactive user) capability to this tutorial?
Hey @Andris!
Thank you for the nice words :)
> Could you please add logout after timeout (logout unactive user) capability to this tutorial?
That simplest way to implement this is with a session timeout: https://symfony.com/doc/cur...
However, another approach would be to set a "lastActiveTime" property on your User object. I would do that by adding a listener to the RequestEvent (previously called kernel.request): it runs at the start of every request. In there, I would check the logged-in-user's "lastActiveTime" against the current time. If it is too long, then invalidate the session. If it is NOT too long, then update lastActiveTime to the current time.
If you have any questions on this, let me know :). I probably won't talk about it in the tutorial, but I'd be happy to answer questions here.
Cheers!
Hey Gustavo D.
There is not an oficial release date yet but this course should happen after "Doctrine Relations" (https://symfonycasts.com/sc... so, it should not take too long :)
Cheers!
Hey azeem!
That's not something we're going to cover, unfortunately. PSR-15 is built on top of PSR-7, which was designed (unfortunately) to be incompatible with Symfony's request/response objects (to be more fair, Symfony could, with some work, change their classes to implement PSR-7, but they don't want to implement it because they/we don't like the dev experience of PSR-7). And so, PSR-15 is awkward to work with in Symfony. There is a bridge that allows it to work - https://symfony.com/doc/cur... - but it's not a main use-case in the Symfony world :).
Cheers!
Hey folks really excited for this course. Any updates on when this will start hitting the wire? Just ran into the fact that Guards are now deprecated and wanted to build using the new system for a new project. Thanks!
Hey Aaron,
Thank you for your interest in SymfonyCasts tutorials! We're releasing a course called "Mastering Doctrine Relations" - it's in the middle right now and will be releasing about 3 week. After that, the next should be "Symfony 5 Security: Authenticators" - it will be based on that "Mastering Doctrine Relations". So, roughly, I think in a month it should be started releasing, at least that's our plan so far :)
Cheers!
Great! I don't know what the odds are of having an LDAP example slipped in to the curriculum might be but that would be great if it could.
Hey @Aaron!
Unfortunately... that won't be included - it's a bit too specific, and nobody can follow along with it unless they have a handy LDAP server :/. But I know from experience that it can be confusing! There is a built-in LDAP authentication mechanism in Symfony, and one of the cool things in the new security system is that these core classes are much more readable (and thus, if you're having trouble figuring something out, it's much more likely reading the core code can give you a clue). For example, here is the core class that handles the LDAP authentication - https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Ldap/Security/LdapAuthenticator.php
This one IS a big more confusing because most of the authentication is done by another authenticator - $this->authenticator. If you're using form_login_ldap
- https://symfony.com/doc/current/security/ldap.html#configuration-example-for-form-login - then that "inner" authenticator is https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php
But really, the hardest part of LDAP is getting the config & logic for loading the users correct... because an LDAP-powered login form is really just a normal login form that loads users from LDAP instead of a traditional database. Ultimately, when it comes time to load the user from LDAP, this is the class & method that will be responsible for doing that - https://github.com/symfony/symfony/blob/6821b55341c6444b45bf3eeebdffe9a0669daa66/src/Symfony/Component/Ldap/Security/LdapUserProvider.php#L75
So, we won't cover it - but we will cover many things "around" all of this - like custom authenticator and user providers. Hopefully that, along with the links above, will help you out :).
Cheers!
Thanx for these great videos, very well made und fully understandable for anyone !
Anyway, it would be very welcome to have one of these videos on "Symfony <> Doctrine <> Elasticsearch" as Elasticsearch is very used for applications and it seems to be a complexe relation between those 3... It could be very useful...
Thank you
Hey Robin,
Agree, ElasticSearch is great, and commonly used. We even use this for search on SymfonyCasts :) Unfortunately, we don't have too much bandwidth for this course right now, but we definitely want to release this course later, so it's in our idea pool, but no any release date yet.
Thank you for your interest in SymfonyCasts tutorials and your patience!
Cheers!
Hey asif khan
For the moment we do not have planned to release a tutorial about SaaS but thanks for letting us know what you'd like to learn next
Cheers!
Hey Symfonycasts! Been enjoying your tutorials!
Recently I need to add some Users to a site, and was wondering when this tutorial is out? Might wait for this to come out before I make changes to the site.
Hi @August
Thanks for you interest in us! I suppose it will came after our new doctrine course, but I can't provide you any eta on it =)
Cheers!
Hey guys, I'm sooo waiting for this tutorial, being a subscriber for 3months - and I must say it's my best investment of all times. The quality of videos and explanation is amazing! I'm sincerely grateful for your job!
Atm have a lesser deadline for a study project, and I'm struggling with a question about email confirmation. Everything seems to work, but even if the user didn't confirmed his email - he is still able to log in. Where and how I could manage this? So the user MUST confirm email, before he able to log in/auto-login after registration. Would be grateful for any replies and tips :)
Hey Andrejus,
I think you can leverage the User::$enabled property for this, just set it to false by default and users won't be able login anymore. Then, set it to true when users confirmed their emails. But in this case you would need to tweak the default error message that will be shown when users will try to login, but it's easy to do with translations.
Or probably better to create a separate property for this, e.g. "User::$isEmailConfirmed", and check this in your custom user authenticator. If it's not true - you would need to throw an exception to show users an error message explaining why they cannot login.
Btw, I would recommend you to leverage this bundle: https://github.com/SymfonyC... - it has docs explaining how to set up and configure it. We're also going to cover this bundle in our Symfony 5 Security course which in rough might be started releasing in about a month I think :)
I hope this helps!
Cheers!
Would is be possible to add a example of login after registration using new authentication system , i don't find any example in the internet
Hi @mslimen
You won't believe how simple is the solution. So after persisting your user to database you should do following things:
Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface $userAuthenticator
App\Security\Authentication\LoginFormAuthenticator $loginFormAuthenticator
class RegistrationController extends AbstractController
{
// ...
public function register(Request $request, UserAuthenticatorInterface $userAuthenticator, LoginFormAuthenticator $loginFormAuthenticator/.../): Response
{
// ...
if ($form->isSubmitted() && $form->isValid()) {
// ...
return $userAuthenticator->authenticateUser($newUser, $loginFormAuthenticator, $request)
}
// ...
}
// ...
}
I hope that will help!
Cheers!
Would is be possible to add a brief example of a registration process to this tutorial? I'm not quite sure if the route belongs in a security controller or its own controller.
And, to help you out before the tutorial, I usually do put registration in its own controller (separate from security), but I think both places are fine. I'd recommend using make:registration-form
from MakerBundle to help you build all of this :).
Cheers!
Hey wLcDesigns,
Thank you for your interest in SymfonyCasts tutorials! Yes, we're going to cover registration process in this tutorial ;)
Cheers!
Maybe You can cover google recaptcha v3?