Bumping before I tear my hair out :)
SSO Server with dedicated Socialite Provider
Hello all,
I'm so sorry for this super long thread, but I wanted to provide as much information as possible to keep the amount of back and forth to a minimum :)
I recently posted a thread asking how I should go about establishing some kind of connection between multiple Laravel applications - thankfully I was nudged in the direction of a dedicated SSO application.
I now, currently have three applications - one of which is my SSO application - the other two are SAAS apps. Here's a quick overview of each one.
- Hub - The dedicated SSO application. This is where all of the users and their roles will be managed. I'm using the lucadegasperi/oauth2-server-laravel package to do this.
- Grub - Very small ecommerce app we use to keep track of "snacks" in-house.
- Safe - A password management app. Of which is currently still in development, so I won't really go into any details about this as it'll follow the same suit as the Grub app - using the dedicated Socialite driver.
I'm having a few problems at the moment, where the token is return null and therefore leading to further issues where it's unable to fetch the user. Here's what I currently have.
Hub
As mentioned above, I have the lucadegasperi/oauth2-server-laravel package installed, everything has been migrated, I believe I have everything configured correctly and I have chosen my grant - the Authorization code grant.
After following the implementation guide for the Auth code grant - my routes for the Hub app look a little something like this.
// Me
Route::get('me', ['as' => 'oauth.me', 'uses' => 'Auth\OAuthController@getMe']);
// OAuth & Home
Route::group(['middleware' => 'auth'], function() {
Route::get('oauth/authorize', 'Auth\OAuthController@getAuthorize');
Route::post('oauth/authorize', ['as' => 'oauth.authorize', 'uses' => 'Auth\OAuthController@postAuthorize']);
Route::post('oauth/token', ['as' => 'oauth.token', 'uses' => 'Auth\OAuthController@postToken']);
Route::get('/', ['as' => 'hub', 'uses' => 'HubController@hub']);
});
Which leads me to the OAuthController - of which looks like so:
class OAuthController extends Controller
{
/**
* OAuth Constructor
*/
public function __construct()
{
$this->middleware('check-authorization-params', [
'only' => ['getAuthorize', 'postAuthorize']
]);
}
/**
* Display the Authorization Form
*
* @return Response
*/
public function getAuthorize()
{
$authParams = Authorizer::getAuthCodeRequestParams();
$formParams = array_except($authParams,'client');
$formParams['client_id'] = $authParams['client']->getId();
$formParams['scope'] = implode(config('oauth2.scope_delimiter'), array_map(function ($scope) {
return $scope->getId();
}, $authParams['scopes']));
return view('auth.authorize')->with(['params' => $formParams, 'client' => $authParams['client']]);
}
/**
* Handle the Authorization
*
* @param Request $request
* @return Response
*/
public function postAuthorize(Request $request)
{
$params = Authorizer::getAuthCodeRequestParams();
$params['user_id'] = auth()->id();
$redirectUri = '/';
$redirectUri = Authorizer::issueAuthCode('user', $params['user_id'], $params);
return redirect()->to($redirectUri);
}
/**
* Issue the Access Token
*
* @param Request $request
* @return Resonse
*/
public function postToken(Request $request)
{
return response()->json(Authorizer::issueAccessToken());
}
/**
* Return the Authorized User
*
* @return Response
*/
public function getMe()
{
$user = auth()->user();
return response()->json($user);
}
}
I'm not so sure I have the getMe() method set up correctly - because this isn't mentioned anywhere in the docs. So I'm just guessing how to do it there.
I've then added a sample client to the oauth_clients table and set up the redirect on my oauth_client_endpoints table as seen below.

Grub
I recently saw a reply from @martinbean's, of which he goes on to speak of setting up a dedicated Socialite provider - which I proceeded to do, you can view the source here
Then added an impact service to my services.php config file, which looks like so:
'impact' => [
'url' => 'http://hub.dev',
'client' => 'GrubID',
'secret' => 'GrubSecret',
'redirect' => 'http://grub.dev/test/callback'
]
Of course, all for testing purposes right now. I'll obviously create proper id's and secret's in the future.
I then set up some dummy routes to check everything is working...
Route::get('test', function() {
return \Socialite::driver('impact')->redirect();
});
Route::get('test/callback', function(\Illuminate\Http\Request $request) {
if($request->has('code'))
{
$user = \Socialite::driver('impact')->user();
dd($user);
}
});
I then go hit the http://grub.dev/test route, I'm redirect to http://hub.dev/oauth/authorize with all the parameters as expected - to unfortunately get the following error:
Missing argument 2 for array_get(), called in /home/vagrant/Code/grub/packages/Impact/Socialite/src/ImpactSocialite.php on line 70 and defined
Which if you was to view the Socialite provider's source, is in my mapUserToObject() method.
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => array_get('id'),
'name' => array_get($user, 'name'),
'email' => array_get($user, 'email')
]);
}
But if I do a dd() on the $user, it returns an empty array - leading me to believe I'm not getting a user back from my SSO application? Why might this be?
I hope you can help!
@JoeDawson Yes,
/ OAuth & Home
Route::group(['middleware' => 'auth'], function() {
Route::get('oauth/authorize', 'Auth\OAuthController@getAuthorize');
Route::post('oauth/authorize', ['as' => 'oauth.authorize', 'uses' => 'Auth\OAuthController@postAuthorize']);
//Route::post('oauth/token', ['as' => 'oauth.token', 'uses' => 'Auth\OAuthController@postToken']);
Route::get('/', ['as' => 'hub', 'uses' => 'HubController@hub']);
});
Route::post('oauth/token', ['as' => 'oauth.token', 'uses' => 'Auth\OAuthController@postToken']);
Please or to participate in this conversation.