Code Monkey home page Code Monkey logo

Comments (9)

rwitchell avatar rwitchell commented on July 3, 2024

Hi Shairyar,
You'll need to provide some more info if you want help.

  1. Can you explain your configuration a bit more?
  2. Can you post some of the code which is relevant to the user?
  3. What bundles you are using?
  4. Have you looked at the user in the database to confirm data is correct?

Off the top of my head: i would say you are using the FOSUserBundle - correct?
I too don't want a username and email. I fixed this by doing the following in my entity\user.php

     /**
     * @param string $username
     *
     * @return $this
     */
    public function setUsername($username)
    {
        parent::setUsername($this->email);

        return $this;
    }

To solve the authenticated NO issue, i would say there could be an issue with your config or your authentication or your controller - hard to tell without code.

from oauth2-client-bundle.

shairyar avatar shairyar commented on July 3, 2024

Hi @rwitchell,

Thanks for getting back, I am not using any 3rd party bundle other than oauth2 bundle. I am only having trouble first time when i register, once the user is registered and come through facebook again using the same user things work fine.

Here is my security.yml

security:

    encoders:
        # Our user class and the algorithm we'll use to encode passwords
        # http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
        AppBundle\Entity\User: bcrypt

    providers:
        # Simple example of loading users via Doctrine
        # To load users from somewhere else: http://symfony.com/doc/current/cookbook/security/custom_provider.html
        database_users:
            entity: { class: AppBundle:User, property: username }

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt|error)|css|images|js)/
            security: false

        main:
            anonymous: ~
            logout: ~
            guard:
                authenticators:
                    - app.form_login_authenticator
                    - app.facebook_authenticator
                    - app.linkedin_authenticator
                # by default, use the start() function from FormLoginAuthenticator
                entry_point: app.form_login_authenticator
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, roles: ROLE_ADMIN }
        - { path: ^/candidate, roles: ROLE_JOBSEEKER }

Here is my FacebookConnectController

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\JobSeekerProfile;
use AppBundle\Entity\User;
use AppBundle\Form\JobSeekerRegistrationType;
use League\OAuth2\Client\Provider\FacebookUser;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class FacebookConnectController extends Controller
{
    /**
     * @Route("/connect/facebook", name="connect_facebook")
     */
    public function connectFacebookAction(Request $request)
    {
        // redirect to Facebook
        $facebookClient = $this->get('knpu.oauth2.registry')
            ->getClient('my_facebook_client');

        return $facebookClient->redirect();
    }

    /**
     * @Route("/connect/facebook-check", name="connect_facebook_check")
     */
    public function connectFacebookActionCheck()
    {
        // will not be reached!
    }

    /**
     * @Route("/connect/facebook/registration", name="connect_facebook_registration")
     */
    public function finishRegistration(Request $request)
    {
        /** @var FacebookUser $facebookUser */
        $facebookUser = $this->get('app.facebook_authenticator')
            ->getUserInfoFromSession($request);

        if (!$facebookUser) {
            throw $this->createNotFoundException('How did you get here without user information!?');
        }
        $user = new User();
        $user->setFacebookId($facebookUser->getId());
        $user->setUsername($facebookUser->getEmail());
        $user->setIsActive('1');
        $user->setRoles(array('ROLE_JOBSEEKER'));

        $JS = new JobSeekerProfile();
        $JS->setFirstName($facebookUser->getFirstName());
        $JS->setLastName($facebookUser->getLastName());
        $JS->setGender($facebookUser->getGender());
        $JS->setCountry($facebookUser->getHometown());
        $user->setJobSeekerProfile($JS);
        $form = $this->createForm(JobSeekerRegistrationType::class, $user);

        $form->handleRequest($request);
        if ($form->isValid()) {
            // encode the password manually
            $plainPassword = $form['plainPassword']->getData();
            $encodedPassword = $this->get('security.password_encoder')
                ->encodePassword($user, $plainPassword);
            $user->setPassword($encodedPassword);

            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->persist($JS);
            $em->flush();

            // remove the session information
            $request->getSession()->remove('facebook_user');

            // log the user in manually
            $guardHandler = $this->container->get('security.authentication.guard_handler');
            return $guardHandler->authenticateUserAndHandleSuccess(
                $user,
                $request,
                $this->container->get('app.facebook_authenticator'),
                'main' // the firewall key
            );
        }

        return $this->render('AppBundle::registration.html.twig', array(
            'form' => $form->createView()
        ));
    }
}

Here is my User Entity

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;


class User implements UserInterface, AdvancedUserInterface
{

    private $id;
    private $username;
    private $password;    
    private $roles = array();
    private $isActive;
    private $apiToken;
    private $lastLoginTime;   
    private $facebookId;
    private $linkedinId;

    /**
     * @var \AppBundle\Entity\JobSeekerProfile
     */
    private $jobSeekerProfile;

    public function __construct()
    {
        $this->apiToken = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
    }

    public function getId()
    {
        return $this->id;
    }

    public function getPassword()
    {
        return $this->password;
    }
    public function setPassword($password)
    {
        $this->password = $password;
    }

    /**
     * Returns the roles or permissions granted to the user for security.
     */
    public function getRoles()
    {
        $roles = $this->roles;

        // guarantees that a user always has at least one role for security
        if (empty($roles)) {
            $roles[] = 'ROLE_JOBSEEKER';
        }

        return array_unique($roles);

    }

    public function setRoles($roles)
    {
        $this->roles = $roles;
    }

    /**
     * Returns the salt that was originally used to encode the password.
     */
    public function getSalt()
    {
        return;
    }

    public function getUsername()
    {
        return $this->username;
    }
    /**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }
    /**
     * Removes sensitive data from the user.
     */
    public function eraseCredentials()
    {
        // if you had a plainPassword property, you'd nullify it here
        // $this->plainPassword = null;
    }

    /**
     * @param string $apiToken
     */
    public function setApiToken($apiToken)
    {
        $this->apiToken = $apiToken;
    }

    public function setLastLoginTime(\DateTime $lastLoginTime)
    {
        $this->lastLoginTime = $lastLoginTime;
    }

    public function getFacebookId()
    {
        return $this->facebookId;
    }

    public function setFacebookId($facebookId)
    {
        $this->facebookId = $facebookId;
    }

    /**
     * Get apiToken
     *
     * @return string
     */
    public function getApiToken()
    {
        return $this->apiToken;
    }

    /**
     * Get lastLoginTime
     *
     * @return \DateTime
     */
    public function getLastLoginTime()
    {
        return $this->lastLoginTime;
    }

    /**
     * Set linkedinId
     *
     * @param string $linkedinId
     *
     * @return User
     */
    public function setLinkedinId($linkedinId)
    {
        $this->linkedinId = $linkedinId;

        return $this;
    }

    /**
     * Get linkedinId
     *
     * @return string
     */
    public function getLinkedinId()
    {
        return $this->linkedinId;
    }

    public function isAccountNonExpired()
    {
        return true;
    }


    public function isAccountNonLocked()
    {
        return true;
    }


    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    public function getIsActive()
    {
        return $this->isActive;
    }

    public function setJobSeekerProfile(\AppBundle\Entity\JobSeekerProfile $jobSeekerProfile = null)
    {
        $this->jobSeekerProfile = $jobSeekerProfile;
        $jobSeekerProfile->setJobSeekerUser($this);
        return $this;
    }

    public function getJobSeekerProfile()
    {
        return $this->jobSeekerProfile;
    }

}

from oauth2-client-bundle.

weaverryan avatar weaverryan commented on July 3, 2024

Hmm, this is tricky. The biggest reason for the "Authenticated No" thing is that your user has no roles - in fact it's the only way that I'm aware of for this to happen. When you see "Authenticated No" - what roles does it show in the web debug toolbar / profiler? Your User class looks correct - it looks like it always returns at least one role, but I still think this is the issue somehow.

from oauth2-client-bundle.

shairyar avatar shairyar commented on July 3, 2024

The role is see is ROLE_JOBSEEKER..

from oauth2-client-bundle.

shairyar avatar shairyar commented on July 3, 2024

I think problem occurs when using AdvancedUserInterface if I get rid of AdvancedUserInterface from my User entity things start working fine, i am able to register the first time it self and Authenticated is Yes but the moment I put back AdvancedUserInterface the registration process breaks down and i am not authenticated the first time. At the moment all i have in the methods of AdvancedUserInterface is as following.

public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

from oauth2-client-bundle.

weaverryan avatar weaverryan commented on July 3, 2024

Ah, nice detective work! If you simply return true from isEnabled, does that fix it (I imagine it does)? Also, can you double-check that isActive is true after you finish registration (right before you make the Guard call). I'm sure it is - but trying to find the issue :). Finally, does your User class implement the SerializableInterface? And if so, is the isActive field included in the serialized data (it should be).

There are some pitfalls - especially when using AdvancedUserInterface - it may be one of those, or may be Guard related - I'm not sure yet :).

Thanks!

from oauth2-client-bundle.

shairyar avatar shairyar commented on July 3, 2024

Hi,

Ah, nice detective work! If you simply return true from isEnabled, does that fix it (I imagine it does)?

Yes if I hardcode this inside the Entity it does fix the problem.

    public function isEnabled()
    {
        return true;
    }

Also, can you double-check that isActive is true after you finish registration (right before you make the Guard call).

I am already doing this as I am saving the isActive value inside database

Finally, does your User class implement the SerializableInterface? And if so, is the isActive field included in the serialized data (it should be).

No I am not using SerializableInterface

from oauth2-client-bundle.

weaverryan avatar weaverryan commented on July 3, 2024

@shairyar if you're able to post a small project with this issue, I can debug further. Unfortunately, I can't seem to repeat this locally, even if I use AdvancedUserInterface. Typically, this occurs because after you login, on the next request, this hasChangedMethod on your token returns false. In your case, somehow, the isEnabled return value is changing - something related to how the User object is being serialized :/. It still may be a legitimate issue, but if it is, it's subtle.

from oauth2-client-bundle.

shairyar avatar shairyar commented on July 3, 2024

I think we can close this issue for now, i will investigate more and create the small project if this issue resurface again. Many thanks for all the help.

from oauth2-client-bundle.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.