OAuth2
OAuth2 Authentication
OAuth2 is a standard protocol for authorization that allows users to grant third-party applications access to their resources without sharing credentials.
Overview
OAuth2 is ideal for:
- APIs that support the OAuth2 standard
- User-specific authentication where you need access to user data
- Services where you want to avoid storing user credentials
Configuration
In your spec.yml:
auth:
type: oauth2
# Method implementations
getOAuthConfig:
implementationType: mapping
makeApiClient:
implementationType: mapping
test:
implementationType: javascript
# Optional method implementations
getTokenData:
implementationType: javascript
getCredentialsFromTokenResponse:
implementationType: javascript
refreshCredentials:
implementationType: javascript
OAuth2 Config
The OAuth2 configuration is defined in a mapping file:
# File: auth/get-oauth-config.map.yml
clientId:
$var: connectorParameters.clientId
clientSecret:
$var: connectorParameters.clientSecret
authorizeUri: https://auth.example.com/oauth2/authorize
tokenUri: https://auth.example.com/oauth2/token
scopes:
- read
- write
clientAuthLocation: body # or 'headers'
noRefreshToken: false
skipPkce: false
extra:
prompt: consent
access_type: offline
Config Parameters
Parameter | Description |
---|---|
clientId | The OAuth2 client ID (usually from connector parameters) |
clientSecret | The OAuth2 client secret |
authorizeUri | The endpoint where users are redirected to authenticate |
tokenUri | The endpoint where access tokens are obtained |
scopes | List of OAuth scopes to request |
clientAuthLocation | Where to send client credentials (headers , body , or both if not specified) |
noRefreshToken | Set to true if the API doesn't support refresh tokens |
skipPkce | Set to true if the API doesn't support PKCE |
extra | Additional parameters to add to the authorize URI |
OAuth2 Flow Implementation
Standard OAuth2 Flow
The standard OAuth2 flow works like this:
- User initiates authentication
- Integration.app redirects user to the
authorizeUri
with appropriate parameters - User authenticates with the service and grants permissions
- Service redirects back to Integration.app with an authorization code
- Integration.app exchanges the code for access and refresh tokens
- The tokens are stored as connection credentials
- Integration.app uses the access token for API requests
Custom Token Request
If you need to customize the token exchange process, you can implement a custom getTokenData
method:
// File: auth/get-token-data.js
exports.getTokenData = async function({
connectorParameters,
connectionParameters,
codeVerifier,
queryParameters,
redirectUri
}) {
// Custom implementation of token retrieval
const response = await fetch(connectorParameters.tokenUri, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: queryParameters.code,
redirect_uri: redirectUri,
client_id: connectorParameters.clientId,
client_secret: connectorParameters.clientSecret,
code_verifier: codeVerifier
// Add any custom parameters here
})
});
return await response.json();
};
Custom Credentials Extraction
If you need to modify the tokens or make additional API calls after the token exchange, implement the getCredentialsFromTokenResponse
method:
// File: auth/get-credentials-from-token-response.js
exports.getCredentialsFromTokenResponse = async function({
connectorParameters,
connectionParameters,
queryParameters,
tokenResponse
}) {
// You can transform the token response or make additional API calls
// For example, get user information
const userInfoResponse = await fetch('https://api.example.com/userinfo', {
headers: {
'Authorization': `Bearer ${tokenResponse.access_token}`
}
});
const userInfo = await userInfoResponse.json();
// Return combined credentials
return {
// Include fields from token response if needed
access_token: tokenResponse.access_token,
refresh_token: tokenResponse.refresh_token,
// Add custom fields
userId: userInfo.id,
userName: userInfo.name
};
};
Custom Token Refresh
See refreshCredentials for more details.
If the API uses a non-standard token refresh mechanism, implement the refreshCredentials
method:
// File: auth/refresh-credentials.js
exports.refreshCredentials = async function({
connectorParameters,
connectionParameters,
credentials
}) {
// Custom implementation for refreshing tokens
const response = await fetch(connectorParameters.tokenUri, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: credentials.refresh_token,
client_id: connectorParameters.clientId,
client_secret: connectorParameters.clientSecret
// Add any custom parameters here
})
});
const refreshResponse = await response.json();
// Return the new credentials (they will be merged with existing credentials)
return {
access_token: refreshResponse.access_token,
// Include refresh_token if it was returned
refresh_token: refreshResponse.refresh_token || credentials.refresh_token,
// Update expiration if available
expires_at: refreshResponse.expires_in
? Date.now() + (refreshResponse.expires_in * 1000)
: undefined
};
};
Updated 16 days ago