← Back to all snippets
JAVASCRIPT

OAuth 2.0 Client Credentials for Server API Calls

Authenticate server-to-server API requests securely using the OAuth 2.0 Client Credentials flow, ideal for background services and daemon applications without user interaction.

/**
 * Obtains an OAuth 2.0 access token using the Client Credentials grant type.
 * @param {string} tokenUrl - The OAuth token endpoint URL.
 * @param {string} clientId - Your application's client ID.
 * @param {string} clientSecret - Your application's client secret.
 * @param {string} scope - The requested scopes (space-separated string).
 * @returns {Promise<string>} The access token.
 * @throws {Error} If token acquisition fails.
 */
async function getOAuthAccessToken(tokenUrl, clientId, clientSecret, scope = '') {
    const authString = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
    const params = new URLSearchParams();
    params.append('grant_type', 'client_credentials');
    if (scope) {
        params.append('scope', scope);
    }

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

    if (!response.ok) {
        const errorData = await response.json().catch(() => ({ message: 'Unknown error' }));
        throw new Error(`Failed to get access token: ${response.status} - ${errorData.error_description || errorData.message}`);
    }

    const data = await response.json();
    return data.access_token;
}

/**
 * Makes an authenticated API call using a provided access token.
 * @param {string} apiUrl - The target API endpoint.
 * @param {string} accessToken - The OAuth access token.
 * @param {object} options - Fetch options.
 * @returns {Promise<Response>} The API response.
 */
async function makeAuthenticatedApiCall(apiUrl, accessToken, options = {}) {
    return fetch(apiUrl, {
        ...options,
        headers: {
            ...options.headers,
            'Authorization': `Bearer ${accessToken}`
        }
    });
}

// Example usage (Node.js environment, as `Buffer` is used):
// (async () => {
//     const TOKEN_URL = 'https://oauth.example.com/token';
//     const CLIENT_ID = process.env.OAUTH_CLIENT_ID;
//     const CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET;
//     const API_URL = 'https://api.example.com/resource';

//     try {
//         const accessToken = await getOAuthAccessToken(TOKEN_URL, CLIENT_ID, CLIENT_SECRET, 'read write');
//         console.log('Access Token acquired:', accessToken);

//         const apiResponse = await makeAuthenticatedApiCall(API_URL, accessToken, {
//             method: 'GET',
//             headers: { 'Accept': 'application/json' }
//         });

//         if (!apiResponse.ok) {
//             throw new Error(`API call failed: ${apiResponse.status}`);
//         }
//         const data = await apiResponse.json();
//         console.log('API Response:', data);

//     } catch (error) {
//         console.error('Authentication or API call error:', error.message);
//     }
// })();
How it works: This snippet demonstrates how to securely authenticate with an API using the OAuth 2.0 Client Credentials grant type. This flow is ideal for server-to-server communication where no end-user is involved. The `getOAuthAccessToken` function exchanges client ID and secret for an access token, which is then used by `makeAuthenticatedApiCall` to authorize subsequent requests. This method ensures that sensitive credentials are not exposed client-side and provides a robust way for backend services to interact with protected APIs.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs