
CalumO.82120 (Customer) asked a question.
Created a new HTTPS GET function card in Okta Workflows to communicate with Googles Contacts API. (https://www.google.com/m8/feeds/contacts/atko.mygbiz.com/full)
Configured the connection with OAuth2 successfully using the link here: https://help.okta.com/en/prod/Content/Topics/Workflows/function-reference/HTTP/http_authorization.htm , and the flow works successfully as anticipated.
However, after an hour, the flow fails with a 500 error, then not long after a 401 error:
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
It seems like the access token expires after an hour, and the HTTP Connection doesn't automatically attempt to refresh the token or gain a new token.
Do any options exist to automatically refresh the token?

Hi Calum,
You may use the Scope that is referred in this article here https://help.okta.com/en/prod/Content/Topics/Workflows/function-reference/HTTP/http_authorization.htm
You may need to confirm that you are requesting the correct scope from the OAuth2 connection to grant the refresh token. You may also need a specific scope for the google contacts API in order to retrieve it.
If you experience any issues I would recommend opening a support ticket by emailing support@okta.com
Hope you have a wonderful day!
To get this working we had to use the entire URL from the Step 2: Redirect to Google's OAuth 2.0 server section of https://developers.google.com/identity/protocols/oauth2/web-server#httprest_2 to generate an authorization code (in the URL of a a captive Okta workflows error window generated when trying to create a connection) being sure to include access_type=offline in the URL
We used that auth code to build out the call to exchange this auth code for a refresh and access token in Postman
In our workflow we make a call to get a new access token using the refresh token, we then use that access token in our API calls to Google that aren't included in the generic Google Workspace connection (anything outside of Directory or Licensing endpoints - in our case it was actually a sub endpoint of Directory for Customer not working to allow us to list all admin roles)
FWIW the raw HTTP request Google template offered in workflows and the linked video do not seem to cover refresh tokens and following the process as advised does result in the token expiring after 1 hour.
Had to re-establish this connection today after the initial account that configured the connection lost admin privileges and wanted to add greater detail regarding this to same some folks the headache:
Navigate to Connections in Okta Workflow panel, add new connection and pick a name and choose oAuth as type
URL: https://accounts.google.com/o/oauth2/v2/auth?client_id=<CLIENT-ID>&response_type=code&access_type=offline&state=state_parameter_passthrough_value&scope=<SCOPE>&redirect_uri=<redirect URI from GCP>&include_granted_scopes=true
Token path: https://accounts.google.com/o/oauth2/v2/token
Client ID: Client ID from GCP project
Client Secret: Client Secret from GCP project
Scopes: DWD Scope to be added, make sure this has been assigned to the client ID in Google Workspace
You will be prompted to log in with an account that has admin access, once attempting to sign in you will see an error like:
In the URL of this window will be authorization code
You can create a POST call to google in Postman/cURL or otherwise in this format as outlined on https://developers.google.com/identity/protocols/oauth2/web-server#httprest_2:
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code
Doing so will return a response with an access token and a refresh token
Create a URL in the format:
https://oauth2.googleapis.com/token?client_id=<CLIENT ID>&client_secret=<SECRET>&refresh_token=<REFRESH TOKEN>&grant_type=refresh_token
With the actual parameters, this URL can be used in an Okta workflow with a POST call to generate an access token, that access token can be passed as a Bearer token to the next step of an Okta workflow to make API calls against Google Workspace (assuming the necessary domain wide delegated access scope has been assigned to the client ID)
Happy workflow building!
Is this still working for you, hit this same problem and trying the above but just getting a 400 Bad Request
If anyone else comes across this post, I did get it working by following the below steps
Oh using the playground seems much cleaner and simpler than my workaround for generating the refresh token, bravo!
Hi Phillip & Zachariah,
I am trying to accomplish this same thing, but I'm unsure how I should use the access token to make an API call.
Should I be using another RAW HTTP card, and insert the access token into the Header?
Any help you could provide would be appreciated!
Hey Jesse,
Yeah if you pass the generated access token as a Bearer Token and then make the call with that object as a Header that is what has worked for me for calls not available through the standard connector.
Thanks for the reply Zachariah!
We ended up needing to setup a new API connector since our original one was set to use OAUTH. Once we did that, passed the bearer token like you showed into the header and we are in business!
Thanks for all the help!
Yep we have this working in production for a Workflow Integration. We have two flows in Okta, the first generates a new token ever hour and stored in a table to be used by other flows.
Token Generation Flow (Each Card i have)
1. Schedule Card
Hourly
2. Object Construct
Host - oauth2.googleapis.com
3. API Connector Raw Request
URL - https://oauth2.googleapis.com/token?client_id=<client_id>&client_secret=<secret>&refresh_token=<refresh
token> &grant_type=refresh_token
Method - Post
Query - {}
Header - Output from Object Construct (Step 2)
4. Object Get
object - Body Response from API Connector
path - access_token
5. Text Compose
6. Create row
I then call that token for my other flows when I need to do a raw API
Have been on leave for a few weeks so sorry for slow response, let me know
how it goes as happy to help
Thank you,
Phil