Introduction

OAuth Refresh Token Flow is a mechanism that allows applications to obtain new access tokens without requiring user reauthentication. This flow is particularly useful for long-lived applications that need continuous access to Salesforce APIs.

Learning Objectives

By the end of this article, you will:

Actors:

  1. Client Application – The app that needs API access.
  2. Salesforce Authorization Server – Issues tokens.
  3. Resource Server (Salesforce API) – The protected API.

Steps:

  1. The client application receives an access token and a refresh token during Web Server Flow or User-Agent Flow.
  2. The access token has a limited lifetime.
  3. When the access token expires, the client sends a refresh token request to the Salesforce authorization server.
  4. If the refresh token is valid, Salesforce responds with a new access token.
  5. The client application uses the new access token for subsequent API requests.

What is Refresh Token Flow?

The Refresh Token Flow allows a client application to request a new access token using a refresh token, avoiding the need for users to log in again.

Why Use Refresh Token Flow?

When to Use Refresh Token Flow?

How Does It Work?

The client application makes a POST request to Salesforce’s token endpoint:

Request:
POST https://login.salesforce.com/services/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&refresh_token=YOUR_REFRESH_TOKEN
Response:
{
"access_token": "NEW_ACCESS_TOKEN",
"instance_url": "https://your-instance.salesforce.com",
"token_type": "Bearer"
}

Implementation Details in Salesforce

A. Generate Refresh Token

To get a refresh token, include offline_access in your OAuth scope when authorizing:

https://login.salesforce.com/services/oauth2/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URI
&scope=full refresh_token
B. Implement in Apex (For Token Refresh in Callouts)
public class OAuthRefreshTokenService {
public static String refreshAccessToken(String refreshToken) {
String clientId = 'YOUR_CLIENT_ID';
String clientSecret = 'YOUR_CLIENT_SECRET';
String tokenUrl = 'https://login.salesforce.com/services/oauth2/token';

HttpRequest req = new HttpRequest();
req.setEndpoint(tokenUrl);
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');

String body = 'grant_type=refresh_token' +
'&client_id=' + EncodingUtil.urlEncode(clientId, 'UTF-8') +
'&client_secret=' + EncodingUtil.urlEncode(clientSecret, 'UTF-8') +
'&refresh_token=' + EncodingUtil.urlEncode(refreshToken, 'UTF-8');

req.setBody(body);

Http http = new Http();
HTTPResponse res = http.send(req);

if (res.getStatusCode() == 200) {
Map<String, Object> responseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
return (String) responseMap.get('access_token');
} else {
System.debug('Error refreshing token: ' + res.getBody());
return null;
}
}
}
C. Implement in JavaScript (For Web Apps)
async function refreshAccessToken(refreshToken) {
const tokenUrl = 'https://login.salesforce.com/services/oauth2/token';

const params = new URLSearchParams({
grant_type: 'refresh_token',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
refresh_token: refreshToken
});

const response = await fetch(tokenUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
});

if (response.ok) {
const data = await response.json();
return data.access_token;
} else {
console.error('Error refreshing token:', await response.text());
return null;
}
}

Advantages and disadvantages

advantages

  1. Seamless User Experience – Keeps users logged in without frequent authentication prompts.
  2. Enhanced Security – Limits exposure of access tokens by using short lifespans.
  3. Efficient API Access – Reduces the need for re-authentication, improving app performance.

disadvantages

  1. Token Storage Risk – If compromised, refresh tokens can be misused for long-term access.
  2. Complex Token Management – Requires secure storage, expiration handling, and revocation logic.
  3. Not Always Permanent – Some policies or admin actions can revoke refresh tokens unexpectedly.

Common Mistakes and Tips

Summary

Quiz / Self-Assessment

  1. What is the primary purpose of the Refresh Token Flow?
    a) Logging in users
    b) Renewing expired access tokens
    c) Storing credentials
  2. Where should refresh tokens be stored securely?
    a) Browser local storage
    b) Plaintext in the database
    c) Secure encrypted storage
  3. What happens if a refresh token expires?
    a) The user is logged out and must reauthenticate
    b) A new refresh token is automatically generated
    c) The API continues working as usual

Conclusion

The Refresh Token Flow is essential for long-term API access in Salesforce. By following best practices and implementing secure token handling, you can ensure a seamless and secure integration for your applications.

Additional Resources

https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_web_server_flow.htm&type=5