You can use the OAuth 2.0 client credentials grant in a server-side ViewModel to obtain an access token and call an external API without an interactive user sign-in.
When to use this flow
Use the client credentials grant for a server-to-server integration. Your application sends its client credentials to the authorization server, receives an access token, and sends that token with later API requests.
For example, a server-side ViewModel can obtain a token for an external API, store the token result temporarily, extract access_token, and use it as a Bearer token in a REST GET or POST.
Do not use this procedure for a user signing in and granting access to resources on their behalf. That is a browser-based authorization-code and refresh-token scenario; see Documentation:Office365 accesstoken and Documentation:External login services in MDriven Turnkey.
What you need from the API provider
Before you build the ViewModel, obtain the integration values from the API provider:
- Token endpoint URL.
- Client identifier.
- Client secret.
- Required request content type and request body format.
- Required scope or other provider-specific parameters, if any.
- The token response property name. The example in this article uses
access_token. - Token lifetime or expiry information, if the provider returns it.
OAuth 2.0 defines the grant type, but providers can use different parameter names and requirements. The values below were demonstrated against an IdentityServer4-compatible endpoint; verify every parameter against the documentation for the API you are calling.
Model the token data
Keep the credentials and token-handling data separate from the business data that the integration processes.
Create transient classes or transient attributes for the short-lived request and response values. A transient value is held for the current ViewModel execution and is not intended as persisted business data.
A practical token-result shape is:
| Value | Purpose | Example |
|---|---|---|
TokenResponse
|
The complete JSON string returned by the token endpoint. | A JSON object containing access_token and other properties.
|
AccessToken
|
The extracted token used in later calls. | The value of the JSON access_token property.
|
TokenExpiry
|
The time at which the token must be replaced, when the provider supplies enough information to calculate it. | A time used by server-side criteria to decide whether to request a new token. |
Treat the client secret and access token as sensitive values. Do not expose them as ordinary client-visible ViewModel fields. Keep token acquisition and external API calls in a server-side ViewModel.
Build the token request
Configure a REST POST action in the server-side ViewModel. The REST operations and their arguments are described in Documentation:Rest API.
- Add a string variable or transient attribute to receive the complete token response, for example
vAccessTokenResult. - Configure the REST POST to call the provider's token endpoint.
- Supply the client identifier and client secret using the authentication method required by that provider.
- Add the required content-type header. In the demonstrated form-post request, the header is
Content-Type: application/x-www-form-urlencoded. - Send the body parameter required for this grant:
grant_type=client_credentials. - Add any provider-required scope or additional parameters.
- Assign the REST POST response to
vAccessTokenResult.
The following illustrates the values to configure. It is a request pattern, not a provider-independent copy-and-paste endpoint:
| Request part | Example value |
|---|---|
| Method | POST
|
| URL | <provider token endpoint>
|
| Header | Content-Type: application/x-www-form-urlencoded
|
| Form body | grant_type=client_credentials
|
| Result target | vAccessTokenResult
|
A successful response is JSON and commonly includes an access_token property along with other token metadata.
Extract the access token
After the POST succeeds, extract the access_token JSON property and assign it to your token value.
In an action, use the string JSON property operation shown in the REST walkthrough to read the property from the response. The essential operation is equivalent to:
vAccessTokenResult.JsonGetProperty('access_token')
Assign that result to the transient AccessToken value. The property name is significant: if your provider returns a different name, use the name in its actual JSON response.
For troubleshooting, first inspect the returned JSON in a controlled development environment. Confirm that the request succeeded and that the property name is exactly access_token before building subsequent calls.
Send the token with API calls
Pass the extracted token to every protected API request using the Bearer authorization scheme.
For example, a REST GET follows this pattern:
vResult := selfVM.RestGet(
'<protected API URL>',
'Bearer',
AccessToken,
''
)
The Office 365 example uses the same pattern with a Graph API endpoint:
vResult := selfVM.RestGet(
'https://graph.microsoft.com/v1.0/me',
'Bearer',
SysSingleton.oclSingleton.CurrentUser.Office365AccessToken,
''
)
The token must be sent with each protected call. Obtaining a token does not automatically authorize unrelated REST operations.
Renew the token on the server
Set up server-side criteria in the ViewModel to acquire a new token before the current token expires. For this grant, the renewal action is another client-credentials token request: run the token POST again, replace AccessToken, and update the expiry value if you track one.
A useful sequence is:
- Before an external API call, evaluate whether there is no token or whether the token is close to expiry.
- If a new token is needed, run the token-request action.
- Extract and store the new
access_tokenin the transient token value. - Run the protected API call with the current token.
Keep this process server-side. A client-side ViewModel or browser-visible field can expose credentials or tokens to users of the application.
Troubleshoot common failures
| Symptom | Check |
|---|---|
| The token request is rejected | Verify the token endpoint, client credentials, required authentication method, Content-Type, and grant_type=client_credentials.
|
| No token can be extracted | Inspect the JSON response and confirm the response property name. Do not assume that every provider uses the same response shape. |
| A protected call is unauthorized | Confirm that the call sends the extracted token using the Bearer scheme and that the token has not expired.
|
| The integration stops working after a period of time | Ensure the server-side criteria acquire a replacement token before expiry. |
| The provider requires a user to sign in | This is not a client-credentials scenario. Use the user authorization guidance in Documentation:Office365 accesstoken instead. |
See also
- Documentation:Rest API
- Documentation:Office365 accesstoken
- Documentation:External login services in MDriven Turnkey
- HowTos:Call Turnkey REST from Javascript
Token acquisition, refresh, and use
Token acquisition, refresh, and use
The client-credentials grant flow can be implemented as a server-to-server OAuth2 flow:
- Set up a call to obtain a token by using the client secret.
- Store the token result in transient classes.
- Use a server-side ViewModel and criteria to refresh the token before it expires.
- Pass the token in subsequent calls to the external service.
OAuth2 parameter names and conventions can vary between providers. Configure the token request according to the requirements of the identity provider or API being used.
