FriendsOfSymfony / FOSFacebookBundle

NOT MAINTAINED - see https://github.com/hwi/HWIOAuthBundle
322 stars 140 forks source link

Force user to complete custom login steps after facebook login #209

Open bassrock opened 11 years ago

bassrock commented 11 years ago

Hi,

Is there a way to force the user to fill out a "Facebook login form" after they have connected to their facebook account? For instance make them pick a password or something else.

Thanks

olgierds commented 11 years ago

I had similar problem and solved it using success_handler for fos_facebook. When user uses facebook login for first time it redirects him to page (in my case: 'username_update') where he has to add username. Also when he doesn't do that, next time he log in, he will be prompted again to update his username

In security.yml I have:

security:
    firewalls:
        public:
            pattern: ^/.*
            fos_facebook:
                app_url: "https://www.facebook.com/apps/application.php?id=xxxxxxxxxxxxxxxx"
                server_url: "http://yyyyyyyyyy"
                login_path: fos_user_security_login
                check_path: fos_facebook_security_check
                default_target_path: /
                success_handler: security.authentication.success_handler
                provider: my_fos_facebook_provider
            form_login:
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                provider: fos_userbundle
            anonymous: true
            logout: true

And in src\Acme\Bundle\Handler\AuthenticationSuccessHandler.php

<?php

namespace Acme\Bundle\Handler;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\RouterInterface;
use Doctrine\ORM\EntityManager;
use Acme\Bundle\Entity\User;

/**
 * Custom authentication success handler
 */
class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
{

   private $router;
   private $em;

   /**
    * Constructor
    * @param RouterInterface   $router
    * @param EntityManager     $em
    */
   public function __construct(RouterInterface $router, $options, EntityManager $em, Session $session)
   {
      $this->router = $router;
      $this->em = $em;
      $this->session = $session;
   }

   /**
    * This is called when an interactive authentication attempt succeeds. This
    * is called by authentication listeners inheriting from AbstractAuthenticationListener.
    * @param Request        $request
    * @param TokenInterface $token
    * @return Response The response to return
    */
   function onAuthenticationSuccess(Request $request, TokenInterface $token)
   {

      if ($token->getUser()->getUsername()  == $token->getUser()->getFacebookId())
      {
         $uri = $this->router->generate('username_update');

         $this->session->set('referer_site_uri', $referer = $request->headers->get('referer'));

         return new RedirectResponse($uri);
      }
      else
      {
        $referer = $request->headers->get('referer');
        return new RedirectResponse($referer);
      }

   }
}

Hope this will help you and others

JeremyPinhel commented 11 years ago

Thx olgierds but what is your services.yml ?

olgierds commented 11 years ago

sorry for such late answer

parameters:
    security.authentication.success_handler.class: Acme\Bundle\Handler\AuthenticationSuccessHandler

services:
    my.facebook.user:
        class: Acme\Bundle\Security\User\Provider\FacebookProvider
        arguments:
            facebook: "@fos_facebook.api"
            userManager: "@fos_user.user_manager"
            validator: "@validator"

    fos_user.registration.form.type:
        class: Acme\Bundle\Form\Type\RegistrationFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: fos_user_registration }

    security.authentication.success_handler:
        class: %security.authentication.success_handler.class%
        public: false
        arguments: [@router, @doctrine.orm.entity_manager, @doctrine.orm.entity_manager, @session]