Refresh Token Flow
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:
- Understand what the Refresh Token Flow is and why it’s needed.
- Learn when and where to use this flow.
- Gain insights into the step-by-step process with a sequence diagram.
- Explore implementation details with a real-world example in Salesforce.
- Recognize common mistakes and best practices.
Actors:
- Client Application – The app that needs API access.
- Salesforce Authorization Server – Issues tokens.
- Resource Server (Salesforce API) – The protected API.
Steps:
- The client application receives an access token and a refresh token during Web Server Flow or User-Agent Flow.
- The access token has a limited lifetime.
- When the access token expires, the client sends a refresh token request to the Salesforce authorization server.
- If the refresh token is valid, Salesforce responds with a new access token.
- 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?
- To maintain seamless user sessions.
- To avoid frequent logins, improving user experience.
- To enhance security by limiting the access token lifespan.
When to Use Refresh Token Flow?
- When access tokens have short expiration times.
- In long-running applications like background jobs or mobile apps.
- For applications using Web Server Flow or User-Agent 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
- Seamless User Experience – Keeps users logged in without frequent authentication prompts.
- Enhanced Security – Limits exposure of access tokens by using short lifespans.
- Efficient API Access – Reduces the need for re-authentication, improving app performance.
disadvantages
- Token Storage Risk – If compromised, refresh tokens can be misused for long-term access.
- Complex Token Management – Requires secure storage, expiration handling, and revocation logic.
- Not Always Permanent – Some policies or admin actions can revoke refresh tokens unexpectedly.
Common Mistakes and Tips
- Mistake 1: Not including
offline_access
in OAuth scope.- Tip: Always store refresh tokens securely (encrypted storage).
- Mistake 2: Using an expired refresh token (refresh tokens can expire in some cases).
- Tip: Handle expired refresh tokens gracefully (prompt users to log in again).
- Mistake 3: Storing refresh tokens insecurely in local storage.
- Tip: Use a secure backend server for token exchange
Summary
- The Refresh Token Flow allows renewing access tokens without user intervention.
- It is useful for applications that need continuous API access.
- The implementation requires sending a refresh token request to Salesforce.
- Apex and JavaScript implementations help automate the token refresh process.
- Security best practices must be followed to protect tokens.
Quiz / Self-Assessment
- What is the primary purpose of the Refresh Token Flow?
a) Logging in users
b) Renewing expired access tokens
c) Storing credentials - Where should refresh tokens be stored securely?
a) Browser local storage
b) Plaintext in the database
c) Secure encrypted storage - 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