Chapters
47 Chapters
|
4:41:51
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
¡Este tutorial también funciona muy bien para Symfony 6!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"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.21.6
"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
}
}
21 Comments
Hi! Thanks for this great tutorial!
But at the last step - add resending response to CheckVerifiedUserSubscriber - went something wrong.
The same code (but Symfony 6) - but instead of being redirected to "app_verify_resend_email" in the browser - appears this error:
Typed property App\EventSubscriber\CheckVerifiedUserSubscriber::$router must not be accessed before initialization
Any hint how to fix it?
Solved! Sorry, my mistake. Wrong typing in construct ...
it happens ;)
Cheers and happy coding!
If one wanted to expand the forced verification beyond the login event to ensure no access to any resources would be accessed by an account that isn't verified would the better way be to create a listener for kernel.request? I have code working doing this but would prefer to know ahead of time if I'm going to cause problems down the road. Here's what I did so far.
services.yaml
UserListener.php
Note this is some legacy code from a proof of concept I built a while back. I tested moving it into the CheckVerifiedUserSubscriber subscribed events and that seems to work fine. Not sure it makes sense to wrap this into that class given that event is more broad in potential use but I'm guessing it would be best to keep the work happening on each request to a minimum.
Hi ! Thanks for the tutorial ! It was precious for me !
So I did all like you but now, I've always a LoginFailureEvent even thought I click on the link into the confirmation mail to verify email address 😭 I'm in a magic loop 😅
Hey Chris
Could you tell me more info about the error. What error message did you get? Does it happen on every request? If so, there must be something wrong in your authenticator's
supports()methodCheers!
Hi MolloKhan !
Thanks for replying me !
I will try to explain with my bad english my problem 😅
So, I installed the bundle verify-email-bundle : https://github.com/SymfonyCasts/verify-email-bundle on my project. It's work fine ! Cool !
But a user not verified can log in. There is not a deny access for the not verified user.
Therefore, I found your tuto and I'm trying to develop it in my project.
It's OK, all users not verified are redirect to the resending email confirmation page "/verify/resend_email".
But, when users come from the link of the email confirmation, they are rejected too after logging in.
"An authentication exception occurred."
This link needs user to log in before being verified.
/eventSubscriber/CheckVerifiedUserSubscriber.php :
`
class CheckVerifiedUserSubscriber implements EventSubscriberInterface
{
}`
src/Controller/RegistrationController.php :
`
#[Route('/verify/resend_email', name: 'app_verify_resend_email')]
`
Do you have an idea for bypass the onLoginFailure when the user click on the link of the confirmation email ?
Because I don't want bypass the log in form before verification for security.
I hope to be understandable 🙏🏻😬
Thanks !
Maybe the only way is to verify their email address without having to be authenticated ?
What do you think ? 😑
Hey Chris
I noticed the bundle support both ways, validating anon and logged in users. You need to decide first what method you want to leverage and then add the code shown in their docs https://github.com/SymfonyC...
I hope it helps. Cheers!
Hey MolloKhan !
Yes I fixed my issue with the anonymous validation. It's Ok now :)
Thanks for your help !
Cheers !
Hi, thanks for the tutorial, but please
"I did include a button to resend the email, but I'll leave the implementation to you." don't say that haha... i don't know what i have to do. I can't understand neither how who commented before me did it. Could you please post the code to re-send the link?, i mean.. It's something what we expected to learn watching this tutorials. Thanks you and have a have a good weekend :)
Hey Leonel D. !
Fair enough :). Here is what I would do:
A) From inside of
CheckVerifiedUserSubscriber- https://symfonycasts.com/screencast/symfony-security/login-failure#codeblock-d5a84a00cc - inside ofonLoginFailure(), I would set the email of the user into the session. Something like:Then, in
resend_verify_email.html.twig, for the "Re-Send Email" link, I would actually make that form with a button so that it POSTs back to the controller when pressed:Finally, in the
resendVerifyEmail()controller method, IF the method is POST, let's re-send the email:Let me know if this helps :).
Cheers!
Thanks for sharing your approach.
I have got one thing to add:
In CheckVerifiedUserSubscriber class you have to add RequestStack $requestRequeststack to the Constructor so that you can use the current Request in the method of the subscriber via
$request = $this->requestStack->getCurrentRequest();Then I also got a question. How can I get the User in the resendVerifyEmail(9 controller method?
Since we are not verified at this point, we can NOT use the controllers $this->getUser() helper an can not access the private non_verified_email property of the session, or am I wrong?
Thanks!
Hey Tristan P.!
Ah, you're right! Thank you - I updated my code above. Actually, you can get the Request even easier with
$event->getRequest()on this case.And, I can see that you answered your other question, but I can see that it wasn't clear in my code. I'll update that as well!
Cheers!
Ok, I am sorry. I can of course get the user in the controller method, I just have get the email from the session via
`
$session->get('non_verified_email');
`
Then I can use the repo to get the user.
I just hat a typo when trying to get the property from the session
"I did include a button to resend the email, but I'll leave the implementation to you."
I used the AuthenticationUtils to get the last username to find out who is trying to resend email. And then made a request via UserRepository (findOneBy) and generated new link.
Did I do it right? :)
Hey there!
Sounds good! But because the last username is in session and it's not robust solution probably. If the users is authenticated - you can try to get it from the controller. If you extends the Symfony abstract controller - you can get the current user with getUser() call. Otherwise, you can inject the Security service that will bring you the same getUser() method to fetch. the currently authenticated user object.
Cheers!
Hi ,
how can I pass the user to the resend route in register controller so i can after that resend the email to him if he click the resend bouton.
i don't pass it into the url since bad personnes can change it and resend verification email to another users .
any solution to do it securely please ?
Hey Khaled L.!
That's a really good question! A simple solution would be to, from the subscriber we create, store the user's id into the session. Then in the resend action, read it from the session (404 if nothing is there), query for the User and re-send the email.
Cheers!
Hi...Works pretty fine. Thanks !
"Houston: no signs of life"
Start the conversation!