public function exchangeCode()
    {
        $code = isset($_GET['code']) ? $_GET['code'] : (isset($_POST['code']) ? $_POST['code'] : null);

        if (! isset($code)) {
            $this->debugInfo('No code found in _GET or _POST params.');
            return false;
        }

        $this->debugInfo('Code: '.$code);

        // Generate the url to the API that will give us the access token and id token
        $auth_url = $this->generateUrl('token');
        // Make the call
        $response = $this->oauth_client->getAccessToken($auth_url, 'authorization_code', [
            'code' => $code,
            'redirect_uri' => $this->redirect_uri
        ], [
            'Auth0-Client' => ApiClient::getInfoHeadersData()->build()
        ]);

        $auth0_response = $response['result'];

        if ($response['code'] !== 200) {
            if (isset($auth0_response['error'])) {
                throw new ApiException($auth0_response['error'].': '.$auth0_response['error_description']);
            } else {
                throw new ApiException($auth0_response);
            }
        }

        $this->debugInfo(json_encode($auth0_response));
        $access_token  = (isset($auth0_response['access_token'])) ? $auth0_response['access_token'] : false;
        $refresh_token = (isset($auth0_response['refresh_token'])) ? $auth0_response['refresh_token'] : false;
        $id_token      = (isset($auth0_response['id_token'])) ? $auth0_response['id_token'] : false;

        if (! $access_token) {
            throw new ApiException('Invalid access_token - Retry login.');
        }

        if (! $id_token) {
            // id_token is not mandatory anymore. There is no need to force openid connect
            $this->debugInfo('Missing id_token after code exchange. Remember to ask for openid scope.');
        }

        // Set the access token in the oauth client for future calls to the Auth0 API
        $this->oauth_client->setAccessToken($access_token);
        $this->oauth_client->setAccessTokenType(Client::ACCESS_TOKEN_BEARER);

        // Set it and persist it, if needed
        $this->setAccessToken($access_token);
        $this->setIdToken($id_token);
        $this->setRefreshToken($refresh_token);

        $userinfo_url = $this->generateUrl('user_info');
        $user         = $this->oauth_client->fetch($userinfo_url);

        $this->setUser($user['result']);

        return true;
    }