Search code examples
symfonyoauth-2.0auth0

How can I access the email address of the logged in Auth0 user in Symfony?


I followed this tutorial to setup Oauth2 login with Auth0 in Symfony.

How can I access the email address of the logged in Auth0 user?

Notes:

  • The login works successfully (oauth2 via google on the auth0 side, then redirected back)
  • $this->getUser() from the controller shows the correct username
  • scopes configured in hwi_oauth.yaml: openid profile email
  • The Auth0 record (on their admin dashboard) contains email addresses for the users
  • The bottom of the article references OAuthUserProvider to get user data but I've loaded the service and get only the username again

My code is the same as the article I referenced.

This is the controller I need access to the email address in, followed by the output of the dd($this->getUser().

class UserController extends AbstractController
{
    /**
     * @Route("/user", name="user")
     */
    public function index()
    {
        dd($this->getUser());

        return $this->render('user/index.html.twig', [
            'controller_name' => 'UserController',
        ]);
    }
}

^ HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser {#580 ▼
#username: "coder1" }


Solution

  • You have to extend your User entity with HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser Class, and extend the HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider Class with your own.

    Then register it as a service and use that in your firewall settings. Here is an article walking through it: https://inchoo.net/dev-talk/symfony-hwioauthbundle-and-google-sign-in/

    In your OAuthUserProvider class you can modify the loadUserByOAuthUserResponse and load your user from database.

    Here are the important code pieces:

    update your firewall

    oauth_user_provider:
        service: ib_user.oauth_user_provider
    

    add the services

    hwi_oauth.user.provider.entity:
        class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider
    ib_user.oauth_user_provider:
        class: Foggyline\Bundle\TickerBundle\Auth\OAuthProvider
        arguments: [@session, @doctrine, @service_container]
    

    Here is the OAuthProvider class I'm using:

    <?php
    
    namespace App\Auth;
    
    use App\Repository\UserRepository;
    use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider;
    use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
    use App\Entity\User;
    
    class OAuthProvider extends OAuthUserProvider
    {
        protected $session, $doctrine, $admins, $userRepository;
    
        public function __construct($session, $doctrine, $service_container, UserRepository $userRepository)
        {
            $this->session = $session;
            $this->doctrine = $doctrine;
            $this->container = $service_container;
            $this->userRepository = $userRepository;
        }
    
        public function loadUserByUsername($username)
        {
            $result = $this->userRepository->findBy(['name' => $username]);
    
            if (count($result)) {
                return $result[0];
            } else {
                return new User($username);
            }
        }
    
        public function loadUserByEmail($email)
        {
            $result = $this->userRepository->findBy(['email' => $email]);
    
            if (count($result)) {
                return $result[0];
            } else {
                return new User($email);
            }
        }
    
        public function loadUserByOAuthUserResponse(UserResponseInterface $response)
        {
            //Data from response
            $email = $response->getEmail();
            $nickname = $response->getNickname();
            $realname = $response->getRealName();
            $avatar = $response->getProfilePicture();
    
            //set data in session
            $this->session->set('email', $email);
            $this->session->set('nickname', $nickname);
            $this->session->set('realname', $realname);
            $this->session->set('avatar', $avatar);
    
            $result = $this->userRepository->findBy(['email' => $email]);
    
            if (!count($result)) {
                $user = new User($email);
                $user->setName($realname);
                $user->setEmail($email);
                $user->setRoles(['ROLE_USER']);
    
                $factory = $this->container->get('security.encoder_factory');
                $encoder = $factory->getEncoder($user);
                $password = $encoder->encodePassword(md5(uniqid()), $user->getSalt());
                $user->setPassword($password);
            } else {
                $user = $result[0];
                $user->setUsername($realname);
            }
    
            $em = $this->doctrine->getManager();
            $em->persist($user);
            $em->flush();
    
            //set id
            $this->session->set('id', $user->getId());
    
            return $this->loadUserByEmail($response->getEmail());
        }
    }