'Google Apps script state token is invalid or has expired

Connecting to non-Google Service from a Gmail add-on using OAuth2. In the resource server part use Laravel Passport (here's an example of using Laravel Passport).Getting state token is invalid or has expired error when click Authorize after filling login and password.

Here's my code:

function accessProtectedResource(url, method_opt, headers_opt) {
  var service = getOAuthService();
  var maybeAuthorized = service.hasAccess();
  if (maybeAuthorized) {
    // A token is present, but it may be expired or invalid. Make a
    // request and check the response code to be sure.

    // Make the UrlFetch request and return the result.
    var accessToken = service.getAccessToken();
    var method = method_opt || 'get';
    var headers = headers_opt || {};
    headers['Authorization'] =
        Utilities.formatString('Bearer %s', accessToken);
    var resp = UrlFetchApp.fetch(url, {
      'headers': headers,
      'method' : method,
      'muteHttpExceptions': true, // Prevents thrown HTTP exceptions.
    });

    var code = resp.getResponseCode();
    if (code >= 200 && code < 300) {
      return resp.getContentText("utf-8"); // Success
    } else if (code == 401 || code == 403) {
       // Not fully authorized for this action.
       maybeAuthorized = false;
    } else {
       // Handle other response codes by logging them and throwing an
       // exception.
       console.error("Backend server error (%s): %s", code.toString(),
                     resp.getContentText("utf-8"));
       throw ("Backend server error: " + code);
    }
  }

  if (!maybeAuthorized) {
    // Invoke the authorization flow using the default authorization
    // prompt card.
    CardService.newAuthorizationException()
        .setAuthorizationUrl(service.getAuthorizationUrl())
        .setResourceDisplayName("Display name to show to the user 321")
        .throwException();
  }
}

function getOAuthService() {
  return OAuth2.createService('Test Gmail add-on2')
      .setAuthorizationBaseUrl('https://example.com/oauth/authorize')
      .setTokenUrl('https://example.com/oauth/token')
      .setClientId(4)
      .setClientSecret('qwerty_client_secret')
      .setScope('')
      .setCallbackFunction('authCallback')
      .setParam('response_type', 'code')
      .setParam('state', getCallbackURL('authCallback'))
      .setCache(CacheService.getUserCache())
      .setPropertyStore(PropertiesService.getUserProperties());
}

function getCallbackURL(callbackFunction) {
  // IMPORTANT: Replace string below with the URL from your script, minus the /edit at the end.
  var scriptUrl = 'https://script.google.com/macros/d/qwertyuyuioplkjjhggsdfgfgs';
  var urlSuffix = '/usercallback?state=';
  var stateToken = ScriptApp.newStateToken()
      .withMethod(callbackFunction)
      .withTimeout(120)
      .createToken();
  return scriptUrl + urlSuffix + stateToken;
}

function authCallback(callbackRequest) {
  var authorized = getOAuthService().handleCallback(callbackRequest);
  if (authorized) {
    return HtmlService.createHtmlOutput(
      'Success! <script>setTimeout(function() { top.window.close() }, 1);</script>');
  } else {
    return HtmlService.createHtmlOutput('Denied');
  }
}

function resetOAuth() {
  getOAuthService().reset();
}

UPDATED:

Attached screen of error dialog.

screen of error

This is error link with two state query parameter - https://script.google.com/a/macros/domain.com/d/SCRIPT_ID/usercallback?code=SOME_CODE&state=https%3A%2F%2Fscript.google.com%2Fmacros%2Fd%2F1Y4O73MuraCLhHstyykqNcA5SYtyiwQvYeFaJWdPJOtxWY57cj0WLDKEh%2Fusercallback%3Fstate%3SOME_LONG_HASH



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source