CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simple-oauth2

Node.js client for OAuth2

Pending
Overview
Eval results
Files

client-credentials.mddocs/

Client Credentials Grant

The Client Credentials Grant is used for service-to-service authentication where no user interaction is required. This flow is typically used for server-to-server communications, background jobs, or microservices.

Overview

This grant type implements the OAuth 2.0 Client Credentials flow, which directly exchanges client credentials for an access token without user involvement. The client authenticates using its own credentials rather than acting on behalf of a user.

Core Import

const { ClientCredentials } = require('simple-oauth2');

Client Credentials Class

Constructor

constructor(options: OAuth2Config): ClientCredentials

Creates a new ClientCredentials instance with OAuth 2.0 configuration validation.

Parameters:

  • options - OAuth 2.0 configuration object (see main documentation)

Example:

const client = new ClientCredentials({
  client: {
    id: 'your-client-id',
    secret: 'your-client-secret'
  },
  auth: {
    tokenHost: 'https://oauth-provider.com',
    tokenPath: '/oauth/token'
  }
});

Get Access Token

getToken(params?: ClientCredentialsParams, httpOptions?: any): Promise<AccessToken>

Requests an access token using client credentials.

Parameters:

  • params.scope (string | string[], optional) - Application scopes to request
  • Additional parameters are automatically serialized for the token request
  • httpOptions (object, optional) - HTTP options passed to underlying request library

Returns: Promise resolving to AccessToken instance

Example:

// Basic token request
const accessToken = await client.getToken();

// Token request with specific scopes
const accessToken = await client.getToken({
  scope: ['read:users', 'write:data']
});

// Token request with custom HTTP options
const accessToken = await client.getToken({
  scope: 'api:access'
}, {
  timeout: 10000,
  headers: {
    'User-Agent': 'MyApp/1.0'
  }
});

console.log('Access token:', accessToken.token.access_token);
console.log('Expires at:', accessToken.token.expires_at);

Create Token from Object

createToken(token: any): AccessToken

Creates an AccessToken instance from a plain token object (e.g., from storage).

Parameters:

  • token - Plain object representing an access token conforming to RFC 6750

Returns: AccessToken instance with full token management capabilities

Example:

// Restore token from database
const storedToken = await database.getToken('client-credentials-token');
const accessToken = client.createToken(storedToken);

// Check if token is still valid
if (!accessToken.expired()) {
  // Use existing token
  console.log('Using cached token');
} else {
  // Get new token
  const newToken = await client.getToken();
  await database.saveToken('client-credentials-token', newToken.token);
}

Type Definitions

interface ClientCredentialsParams {
  scope?: string | string[];
  [key: string]: any;
}

Common Usage Patterns

Basic Service Authentication

const { ClientCredentials } = require('simple-oauth2');

const client = new ClientCredentials({
  client: {
    id: process.env.CLIENT_ID,
    secret: process.env.CLIENT_SECRET
  },
  auth: {
    tokenHost: 'https://api.example.com',
    tokenPath: '/oauth/token'
  }
});

// Get token for API access
const accessToken = await client.getToken({
  scope: 'api:read api:write'
});

// Use token for API requests
const response = await fetch('https://api.example.com/data', {
  headers: {
    'Authorization': `Bearer ${accessToken.token.access_token}`,
    'Content-Type': 'application/json'
  }
});

Token Caching with Automatic Refresh

class APIClient {
  constructor(clientConfig) {
    this.oauth = new ClientCredentials(clientConfig);
    this.cachedToken = null;
  }

  async getValidToken() {
    // Check if we have a cached token that's not expired
    if (this.cachedToken && !this.cachedToken.expired(300)) { // 5 min buffer
      return this.cachedToken;
    }

    // Get new token
    this.cachedToken = await this.oauth.getToken({
      scope: 'api:access'
    });

    return this.cachedToken;
  }

  async makeAPIRequest(endpoint, options = {}) {
    const token = await this.getValidToken();
    
    return fetch(endpoint, {
      ...options,
      headers: {
        ...options.headers,
        'Authorization': `Bearer ${token.token.access_token}`
      }
    });
  }
}

// Usage
const apiClient = new APIClient({
  client: {
    id: process.env.CLIENT_ID,
    secret: process.env.CLIENT_SECRET
  },
  auth: {
    tokenHost: 'https://api.example.com'
  }
});

const userData = await apiClient.makeAPIRequest('https://api.example.com/users');

Microservice Authentication

// Microservice A authenticating to Microservice B
const serviceAuth = new ClientCredentials({
  client: {
    id: 'microservice-a-id',
    secret: process.env.SERVICE_SECRET
  },
  auth: {
    tokenHost: 'https://auth.company.com',
    tokenPath: '/oauth/token'
  },
  options: {
    bodyFormat: 'json', // Some services prefer JSON
    authorizationMethod: 'body' // Some services require credentials in body
  }
});

async function callMicroserviceB(data) {
  const token = await serviceAuth.getToken({
    scope: 'microservice-b:access'
  });

  return fetch('https://service-b.company.com/api/process', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token.token.access_token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
}

Install with Tessl CLI

npx tessl i tessl/npm-simple-oauth2

docs

access-token.md

authorization-code.md

client-credentials.md

index.md

resource-owner-password.md

tile.json