Open antonioperic opened 9 years ago
No it is not. FOSOAuthServerBundle is about implementing the server-side part of OAuth. In your case, this is done by Google. What you need is probably https://github.com/hwi/HWIOAuthBundle/ instead
@stof i think HWIO protects rest api after firewall? But my idea is to have complete separeted singlepageapp/mobile app and to do authorization for my api with google access token. I saw some example where this scenario is pulled with custom grant for facebook, but not sure if that is rigth way
@stof something like this http://programmingadvises.blogspot.com/2014/07/symfony-fosoauthserverbundle-access-api.html
What do you think about this approach?
@antonioperic I recommend NOT combining OAuth authentication with your own Rest api. Instead use something like JSON web tokens (jwt), there are Symfony bundles for them or you can use non-framework specific packages.
+1 I am interested in this as well.
Here is another resource touching on the same point by using a custom grant. The comment section does however state this is a security risk. http://blog.tankist.de/blog/2013/08/20/oauth2-explained-part-4-implementing-custom-grant-type-symfony2-fosoauthserverbundle/
There is also a similar question on StackOverflow, but no solution sadly. http://stackoverflow.com/questions/35373319/symfony3-fosoauthserverbundle-and-facebook-or-google-login
hey, I implement this for my REST API + Mobile App. Here is how I solved this problem:
[Mobile App] send a request to my [Authorization Server]
api/oauth/v2/token with parameters:
* client_id
* client_secret
* grant_type = https://domain.com/connect/facebook
* facebook_access_token
Implement the OAuth SDK of your 3rd-party service to get an access token from an authorization code (OAuth2.0 classic workflow). I use the official Facebook SDK for example.
Some CoffeeScript code:
$scope.login = ->
facebookConnectPlugin.login(['email','user_friends','public_profile','user_birthday'], fbLoginSuccess , fbLoginError)
fbLoginSuccess = (userData) ->
$ionicLoading.show
template: '<ion-spinner></ion-spinner>'
fbLogin(userData.authResponse.accessToken)
fbLoginError = (error) ->
$log.error "error facebook login: ", error
fbLogin = (token) ->
UserManager.fbLogin(token).then (res) ->
# Login Success !!
$rootScope.$broadcast('login:refresh')
$ionicLoading.hide()
# go to this after login
$ionicHistory.nextViewOptions
disableBack: true
$state.go 'base.profile.home', {}, {reload: true}
$ionicHistory.clearCache()
.catch (error) ->
# handle server error here
$ionicLoading.hide()
$log.debug 'loginFBerrorCtrl:', error
$scope.error = error
And the UserManager.fbLogin(token)
# Generate userAccessToken from facebook_access_token
AccessTokenFactory.facebookAccessToken = (fbToken) ->
deferred = $q.defer()
$http
method: 'GET'
url: urlBase + 'oauth/v2/token'
params:
client_id: config.oauth_client_id
client_secret: config.oauth_client_secret
grant_type: 'https://welp.fr/connect/facebook'
facebook_access_token: fbToken
.then (response) ->
if response.data.error
deferred.reject response.error_description
else
# Login successful
deferred.resolve response.data.access_token
------------------------------------------------------------------------------------
# Connect with Facebook
UserManager.fbLogin = (fbToken) ->
deferred = $q.defer()
AccessTokenFactory.facebookAccessToken(fbToken)
.then (token) ->
$http
method: 'GET'
url: urlBase + 'users/me'
.then (response) ->
storage.currentUser = JSON.stringify(response.data.entity)
$rootScope.$broadcast 'loginSuccess', storage.currentUser
deferred.resolve response.data.entity
, (error) ->
# forward error
deferred.reject error
deferred.promise
I use the HWIOAuthBundle and a grant-type extension to validate the Facebook access_token and exchange it against my API access token.
Here it is my OAuth/FacebookGrantExtension.php
<?php
namespace ApiBundle\OAuth;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use FOS\OAuthServerBundle\Storage\GrantExtensionInterface;
use OAuth2\Model\IOAuth2Client;
use HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse;
use AppBundle\Entity\User;
class FacebookGrantExtension implements GrantExtensionInterface
{
protected $userProvider;
protected $resourceOwner;
public function __construct(UserProviderInterface $userProvider, $resourceOwner)
{
$this->userProvider = $userProvider;
$this->resourceOwner = $resourceOwner->getResourceOwnerByName('facebook');
}
/*
* {@inheritdoc}
*/
public function checkGrantExtension(IOAuth2Client $client, array $inputData, array $authHeaders)
{
if (!isset($inputData['facebook_access_token'])) {
return false;
}
// loadUser information
$userInformation = $this->resourceOwner->getUserInformation(array('access_token' => $inputData['facebook_access_token']));
if (empty($userInformation)) {
return false;
}
// loadUser from user provider
$user = $this->userProvider->loadUserByOAuthUserResponse($userInformation);
if (!is_object($user) || !$user instanceof User) {
return false;
}
// Not display registrationCompleted page
$this->userProvider->notDisplayRegisterCompleted($user);
return array(
'data' => $user,
);
}
}
Configure properly the HWIOAuthBundle (for Facebook or Google) and it will works like a charm!!
NOTE: Don't forget to add the grant-type to your client!!!! If you use the command line to create a client:
php app/console welp:oauth-server:client:create --name="Mobile app" --redirect-uri="CLIENT_HOST" --grant-type="authorization_code" --grant-type="password" --grant-type="refresh_token" --grant-type="token" --grant-type="client_credentials" --grant-type="https://domain.com/connect/facebook"
I use this in production for Facebook and I will implement Google soon.
If you have any questions, feel free to ask!
Regards,
Titouan
@Nightbr Hi, i'd like to implement your server-side code but i don't undestand how i have to configure "FacebookGrantExtension" service in service.yml . I tried this configuration:
app.api.oauth.facebook_extension:
class: AppBundle\OAuth\FacebookGrantExtension
arguments:
- '@my.oauth_aware.user_provider.service'
- '@.....'
tags:
- { name: fos_oauth_server.grant_extension, uri: 'http://localhost:8000/connect/facebook' }
What is the value that i have to set in the second argument of "app.api.oauth.facebook_extension" service?
Thank you very much for your help!!
Regards,
Fabrizio
Hey, I'm using the HWIO bundle to manage external OAuth connection from config.yml.
So the resources owner services comes from HWIOAuthBundle.
Here is my configuration for Facebook and Google grant:
welp.api.oauth.facebook_extension: class: ApiBundle\OAuth\FacebookGrantExtension tags: - { name: fos_oauth_server.grant_extension, uri: 'https://welp.fr/connect/facebook' } arguments: - "@app.oauth.user_provider" - "@hwi_oauth.resource_ownermap.main" welp.api.oauth.google_extension: class: ApiBundle\OAuth\GoogleGrantExtension tags: - { name: fos_oauth_server.grant_extension, uri: 'https://welp.fr/connect/google' } arguments: - "@app.oauth.user_provider" - "@hwi_oauth.resource_ownermap.main"
Look at the HWIOAuthBundle for more information: https://github.com/hwi/HWIOAuthBundle/
Thank you very much for your help! It works. 👍
Hi, guys... I didn't work with FOSOAuthServerB before. I have one project, SPA + Hybrid mobile application where user are getting authorized with their Google Account. I want to use that login also as authorization for my REST Api. Is that possible with do with FOSOAuth? I suppose that will be some custom grant?
Anybody with similar experience?