Search code examples
laravellaravel-9laravel-passport

laravel passport - issue token return whether new user was created


I'm using Laravel 9 Passport. On the front-end after a user signs into a social account, I"m passing the provider info to the Auth issueToken method. I'd like to return if a new account was created in Laravel (in contrast to if an account already existed).

In Laravel, my issueToken method looks like this:

 public function issueToken(ServerRequestInterface $request)
    {
        try {

            return $this->server->respondToAccessTokenRequest($request, new Psr7Response);

        } catch (ClientException $exception) {

            //never gets here! code below is meaningless.
            $error = json_decode($exception->getResponse()->getBody());
            throw OAuthServerException::invalidRequest('access_token', object_get($error, 'error.message'));
        }

I have a SocialUserRevolver Model that overrides the resolveUserByProviderCredentials method. Here a createOrGetUser method is called, where a new user record is created, or an existing account is retrieved.

class SocialUserResolver implements SocialUserResolverInterface
{

    /**
     * Resolve user by provider credentials.
     *
     * @param string $provider
     * @param string $accessToken
     *
     * @return Authenticatable|null
     * @throws Exception
     */

    public function resolveUserByProviderCredentials(string $provider, string $accessToken): ?Authenticatable
    {
        $providerUser = null;

        try {
            $providerUser = Socialite::driver($provider)->stateless()->userFromToken($accessToken);

        } catch (Exception $exception) {
            //Log::info('exception: '.$exception->getMessage());
            //throw new Exception($exception->getMessage());
        }

            //if (! $providerUser->getEmail())
            //    throw new Exception('Email address not allowed');

        if ($providerUser) {
            return (new ProviderAccountService())->createOrGetUser($providerUser, $provider);
        }

        return null;
    }
}

I'd like to find a good way to return a new field like "account_created", so the front-end can determine if this was a new account.


Solution

  • This is how I solved this problem:

    In the createOrGetUser() method, if a new user was created I added a session variable:

    session(['user_created' => true]);
    

    Then instead of just returning the default response, I intercept the response, and then create a new response adding in the user_created field from the session data:

                $response = $this->server->respondToAccessTokenRequest($request, new Psr7Response);
    
                $bodyContents = json_decode((string) $response->getBody(), true);
    
                //add user_created field to body contents
                $bodyContents['user_created'] = false;
                if ($requestParams and $requestParams['grant_type'] === 'social')
                    $bodyContents['user_created'] = session('user_created');
    
                return response()
                    ->json($bodyContents, $response->getStatusCode());