/** * Register social login services * * @param Application $app Silex application */ public function register(Application $app) { $app['social-login.controller'] = $app->share(function ($app) { $config = $app['config']->load('social-login'); $controller = new SocialLoginController(); $controller->setSocialLoginService($app['social-login.service'])->setConfig($config)->setServiceFactory(new ServiceFactory())->setSession($app['session']); return $controller; }); $app['social-login.mapper'] = $app->share(function ($app) { return new SocialLoginMapper($app['db'], new SocialLoginEntity()); }); $app['social-login.service'] = $app->share(function ($app) { $service = new SocialLoginService(); $service->setUserService($app['user.service'])->setSocialLoginMapper($app['social-login.mapper'])->setOAuthStorage($app['oauth.storage']); return $service; }); $app->get('/social-login/{provider}', 'social-login.controller:login')->bind('social-login-auth'); $app->get('/social-login/{provider}/link', 'social-login.controller:link')->bind('social-link-auth'); $app->get('/social-login/{provider}/callback', 'social-login.controller:callback')->bind('social-login-callback'); $this->setFirewalls($app); }
/** * Callback for OAuth authentication requests * * @param Request $request * @return Response */ public function callback(Request $request) { // Check to see if this provider exists and has a callback implemented $provider = strtolower($request->attributes->get('provider')); if (!$this->providerExists($provider)) { return $this->createNotFoundResponse(); } if (!method_exists($this, $provider)) { throw new LogicException(sprintf('Callback for provider \'%s\' not implemented', $provider)); } // Use provider service and access token from provider to create a LoginRequest for our app $code = $request->query->get('code'); $providerService = $this->getServiceByProvider($provider); $providerToken = $providerService->requestAccessToken($code); $socialLoginRequest = $this->{$provider}($providerService, $providerToken); // Handle login or link-account request and redirect to the redirect-url $state = (int) $request->query->get('state'); try { if ($state === self::ACTION_LOGIN_WITH_ACCOUNT) { $token = $this->service->handleLoginRequest($socialLoginRequest); } elseif ($state === self::ACTION_LINK_ACCOUNT) { $token = $this->service->handleLinkRequest($socialLoginRequest, $this->session->get('user')); } else { return new Response('State parameter not set', 422); } $redirect = $this->config['redirect-url']; $redirect .= '?' . http_build_query($token); } catch (NoLinkedAccountException $e) { $redirect = $this->config['redirect-url']; $redirect .= '?login_failure=1&error=no_linked_account'; } catch (LinkedAccountExistsException $e) { $redirect = $this->config['redirect-url']; $redirect .= '?login_failure=1&error=account_already_linked'; } catch (OutOfBoundsException $e) { $redirect = $this->config['redirect-url']; $redirect .= '?login_failure=1'; if ($e->getCode() === SocialLoginService::EXCEPTION_ACCOUNT_NOT_FOUND) { $redirect .= '&error=account_not_found'; } } $response = new Response(); $response->setStatusCode(301); $response->headers->set('Location', $redirect); return $response; }