Generic OAuth 2.0 client
Arctic provides a generic client for OAuth 2.0 authorization code flow based on RFC 6749, RFC 7009, and RFC 7636. Please be aware that the client strictly follows the RFCs and may not work with providers that aren't spec-compliant. Some common non-compliant behaviors are:
- Does not support HTTP Basic Authentication scheme for client authentication.
- Returns non-400 status codes for errors.
- Returns custom error JSON response body.
Only client password authentication is supported.
Initialization
Initialize OAuth2Client
with your client ID, client password (secret), and redirect URI. clientSecret
and redirectURI
can be null
.
import { OAuth2Client } from "arctic";
const client = new OAuth2Client(clientId, clientPassword, redirectURI);
Create authorization URL
Use OAuth2Client.createAuthorizationURL()
to create an authorization URL.
import { generateState } from "arctic";
const state = generateState();
const url = client.createAuthorizationURL(authorizationEndpoint, state, scopes);
For PKCE flows, use OAuth2Client.createAuthorizationURLWithPKCE()
.
import { generateState, generateCodeVerifier, CodeChallengeMethod } from "arctic";
const state = generateState();
const codeVerifier = generateCodeVerifier();
const url = client.createAuthorizationURLWithPKCE(
authorizationEndpoint,
state,
CodeChallengeMethod.S256,
codeVerifier,
scopes
);
Validate authorization code
Use OAuth2Client.validateAuthorizationCode()
to validate authorization codes. This returns an OAuth2Tokens
instance, or throw one of OAuth2RequestError
, ArcticFetchError
, or a standard Error
(parse errors).
import { OAuth2RequestError, ArcticFetchError } from "arctic";
try {
const tokens = await client.validateAuthorizationCode(tokenEndpoint, code, null);
const accessToken = tokens.accessToken();
} catch (e) {
if (e instanceof OAuth2RequestError) {
// Invalid authorization code, credentials, or redirect URI
const code = e.code;
// ...
}
if (e instanceof ArcticFetchError) {
// Failed to call `fetch()`
const cause = e.cause;
// ...
}
// Parse error
}
Pass the code verifier for PKCE.
const tokens = await client.validateAuthorizationCode(tokenEndpoint, code, codeVerifier);
Refresh access token
Use OAuth2Client.refreshAccessToken()
to refresh access tokens. This also returns an OAuth2Tokens
instance and throws the same errors as OAuth2Client.validateAuthorizationCode()
.
import { OAuth2RequestError, ArcticFetchError } from "arctic";
try {
const tokens = await client.refreshAccessToken(tokenEndpoint, refreshToken, scopes);
const accessToken = tokens.accessToken();
} catch (e) {
if (e instanceof OAuth2RequestError) {
// Invalid tokens, credentials, or redirect URI
const code = e.code;
// ...
}
if (e instanceof ArcticFetchError) {
// Failed to call `fetch()`
const cause = e.cause;
// ...
}
// Parse error
}
Revoke token
Use OAuth2.revokeToken()
to revoke tokens. This also throws the same errors as OAuth2Client.validateAuthorizationCode()
.
import { OAuth2RequestError, ArcticFetchError } from "arctic";
try {
await client.revokeToken(tokenRevocationEndpoint, token);
} catch (e) {
if (e instanceof OAuth2RequestError) {
// Invalid tokens, credentials, or redirect URI
const code = e.code;
// ...
}
if (e instanceof ArcticFetchError) {
// Failed to call `fetch()`
const cause = e.cause;
// ...
}
// Parse error
}