Fetch Middleware for OAuth2
raw JSON →fetch-mw-oauth2 is a JavaScript library designed to simplify OAuth2 integration with the standard `fetch` API, handling automatic token acquisition and refreshing. Currently at v3.3.1, it supports `authorization_code`, `password`, and `client_credentials` grant types, offers robust error handling, OpenID Connect `id_token` exposure, and includes support for token revocation (RFC 7009) and the `resource` parameter (RFC 8707). Since its v3.0.0 release, the library is ESM-only and has ceased support for Node.js 14 and 16. It primarily functions as a `fetch` wrapper or middleware. This package is in maintenance mode, as development has shifted to its successor, `@badgateway/oauth2-client`, which offers enhanced features and similar functionality.
Common errors
error ReferenceError: require is not defined ↓
const { OAuth2 } = require('fetch-mw-oauth2'); to import { OAuth2 } from 'fetch-mw-oauth2'; and ensure your package.json specifies "type": "module" if running in Node.js. error HTTP 400 Bad Request - Client Authentication Failed ↓
authorizationMethod option, or prefer the client_secret_post method if your server supports it. error Build error (e.g., 'window is not defined', module resolution) when using Vite/Next.js ↓
fetch-mw-oauth2 dependency to version 3.2.0 or newer to resolve browser build issues with modern bundlers. Warnings
breaking Version 3.0.0 introduced a full conversion to ES Modules (ESM) and dropped support for Node.js versions 14 and 16. Projects using CommonJS `require()` syntax or older Node.js runtimes will break. ↓
breaking In v3.0.0, `client_id` and `client_secret` were changed to be strictly percent-encoded as per RFC 6749. This was a breaking change if your server was not strictly compliant with the OAuth2 spec and used special characters in secrets. ↓
gotcha Version 3.1.0 reverted the strict percent-encoding for the `Authorization: Basic` header due to interoperability problems with many real-world OAuth2 servers. The library now defaults to less strict encoding. If strict encoding is required, you must explicitly opt-in using the `authorizationMethod` option. ↓
deprecated This `fetch-mw-oauth2` package is in maintenance mode. The project has been renamed and superseded by `@badgateway/oauth2-client`, which offers a more full-featured and actively developed OAuth2 client. Users are strongly recommended to upgrade. ↓
gotcha Early v3 releases (v3.0.0, v3.1.0) had issues with browser builds, particularly for Vite and Next.js users, due to the ESM conversion. This was addressed in v3.2.0. ↓
gotcha Version 3.3.1 fixed a race condition when multiple function calls were attempting OAuth2 endpoint discovery simultaneously. ↓
Install
npm install fetch-mw-oauth2 yarn add fetch-mw-oauth2 pnpm add fetch-mw-oauth2 Imports
- OAuth2 wrong
const { OAuth2 } = require('fetch-mw-oauth2')correctimport { OAuth2 } from 'fetch-mw-oauth2' - OAuth2 types
import type { OAuth2Options, OAuth2Token } from 'fetch-mw-oauth2' - OAuth2 instance creation and usage
import { OAuth2 } from 'fetch-mw-oauth2'; const oauth2 = new OAuth2({ clientId: 'your-client-id', clientSecret: process.env.OAUTH_CLIENT_SECRET ?? '', // Optional in some cases tokenEndpoint: 'https://auth.example.org/token', }, { accessToken: 'initial-access-token', refreshToken: 'initial-refresh-token', }); const response = await oauth2.fetch('https://api.example.org/data');
Quickstart
import { OAuth2 } from 'fetch-mw-oauth2';
async function authenticateAndFetch() {
// Configure OAuth2 for the client_credentials grant type
const oauth2 = new OAuth2({
grantType: 'client_credentials',
clientId: 'your-client-id',
clientSecret: process.env.OAUTH_CLIENT_SECRET ?? '', // Ensure this is loaded from environment variables
tokenEndpoint: 'https://auth.example.com/token',
scope: 'api:read api:write'
});
try {
// Use the wrapped fetch function which automatically handles Authorization headers and token refreshes
const response = await oauth2.fetch('https://api.example.com/protected-resource', {
method: 'GET',
headers: {
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Fetched data:', data);
} catch (error) {
console.error('Failed to fetch data with OAuth2:', error);
}
}
authenticateAndFetch();