JAVASCRIPT
Implementing OAuth 2.0 Client Credentials Grant in Node.js
Securely obtain an access token using the OAuth 2.0 Client Credentials flow in Node.js for server-to-server API authentication without user interaction.
const axios = require('axios');
const OAUTH_CONFIG = {
TOKEN_URL: 'https://oauth.example.com/token',
CLIENT_ID: process.env.OAUTH_CLIENT_ID,
CLIENT_SECRET: process.env.OAUTH_CLIENT_SECRET,
SCOPE: 'read write' // Optional scope
};
let accessToken = null;
let tokenExpiry = 0;
async function getAccessToken() {
if (accessToken && Date.now() < tokenExpiry) {
console.log('Using cached access token.');
return accessToken;
}
console.log('Fetching new access token...');
try {
const response = await axios.post(
OAUTH_CONFIG.TOKEN_URL,
new URLSearchParams({
'grant_type': 'client_credentials',
'client_id': OAUTH_CONFIG.CLIENT_ID,
'client_secret': OAUTH_CONFIG.CLIENT_SECRET,
'scope': OAUTH_CONFIG.SCOPE
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
accessToken = response.data.access_token;
// Set expiry a bit before the actual expiry to avoid using an expired token
tokenExpiry = Date.now() + (response.data.expires_in - 60) * 1000;
console.log('New access token obtained.');
return accessToken;
} catch (error) {
console.error('Error fetching OAuth token:', error.response ? error.response.data : error.message);
throw new Error('Failed to obtain OAuth access token.');
}
}
async function callProtectedApi(apiUrl) {
try {
const token = await getAccessToken();
const response = await axios.get(apiUrl, {
headers: {
'Authorization': `Bearer ${token}`
}
});
return response.data;
} catch (error) {
console.error('Error calling protected API:', error.response ? error.response.data : error.message);
throw error;
}
}
// Example usage (ensure OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET are set as environment variables):
// (async () => {
// try {
// const apiData = await callProtectedApi('https://api.example.com/protected-resource');
// console.log('Protected API Data:', apiData);
// } catch (e) {
// console.error('Application failed:', e.message);
// }
// })();
How it works: This Node.js snippet demonstrates how to implement the OAuth 2.0 Client Credentials Grant flow, ideal for server-to-server communication where there's no user involved. It requests an access token from an OAuth provider using client ID and secret. The token is then cached and reused until it approaches expiry, minimizing token requests. The `callProtectedApi` function shows how to attach this token to subsequent API requests using the `Authorization: Bearer` header, ensuring secure access to protected resources.