OAuth client library APIs for 50+ major OAuth 1.0a and 2.0 providers
—
Custom token extractors for providers that use non-standard JSON response formats or require special error handling beyond the default OAuth 2.0 token response format. These extractors parse provider-specific token responses and create appropriate token objects.
Facebook-specific token extractor that handles Facebook's non-standard error response format.
public class FacebookAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {
public static FacebookAccessTokenJsonExtractor instance();
// Inherited from OAuth2AccessTokenJsonExtractor
public OAuth2AccessToken extract(Response response) throws IOException;
// Facebook-specific error handling
public void generateError(Response response) throws IOException;
}Facebook returns errors in a non-standard format with specific error structure:
{
"error": {
"message": "This authorization code has been used.",
"type": "OAuthException",
"code": 100,
"fbtrace_id": "DtxvtGRaxbB"
}
}Usage Example:
// Automatically used by FacebookApi
OAuth20Service service = new ServiceBuilder("app_id")
.apiSecret("app_secret")
.build(FacebookApi.instance());
try {
OAuth2AccessToken token = service.getAccessToken("invalid_code");
} catch (FacebookAccessTokenErrorResponse e) {
System.out.println("Facebook Error: " + e.getMessage());
System.out.println("Error Type: " + e.getType());
System.out.println("Error Code: " + e.getCode());
System.out.println("Trace ID: " + e.getFbTraceId());
}Salesforce-specific token extractor that creates SalesforceToken objects with additional Salesforce metadata.
public class SalesforceJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static SalesforceJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Extracts Salesforce-specific fields from token response:
{
"access_token": "00Dxx0000000000!...",
"instance_url": "https://mycompany.salesforce.com",
"id": "https://login.salesforce.com/id/00Dxx.../005xx...",
"token_type": "Bearer",
"issued_at": "1234567890",
"signature": "base64signature"
}OpenID Connect token extractor that creates OpenIdOAuth2AccessToken objects with ID token and claims.
public class OpenIdJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static OpenIdJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Extracts OpenID Connect ID token and decodes JWT claims:
{
"access_token": "ya29.a0...",
"expires_in": 3599,
"refresh_token": "1//0...",
"scope": "openid profile email",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIs..."
}Slack-specific token extractor that creates SlackOAuth2AccessToken objects with user access token information.
public class SlackJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static SlackJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Extracts Slack-specific fields from token response:
{
"ok": true,
"access_token": "xoxb-...",
"token_type": "bearer",
"scope": "channels:read,users:read",
"authed_user": {
"access_token": "xoxp-..."
}
}Fitbit-specific token extractor that creates FitBitOAuth2AccessToken objects with user ID.
public class FitBitJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static FitBitJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Extracts Fitbit user ID from token response:
{
"access_token": "eyJhbGci...",
"expires_in": 28800,
"refresh_token": "c6a3...",
"scope": "activity heartrate location nutrition profile settings sleep social weight",
"token_type": "Bearer",
"user_id": "26FWFL"
}Polar-specific token extractor that creates PolarOAuth2AccessToken objects with user IDs.
public class PolarJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static PolarJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Extracts Polar user information from token response:
{
"access_token": "8fdf2a...",
"token_type": "bearer",
"x_user_id": 1234567,
"user_id": 1234567
}VKontakte-specific token extractor for Russian social network token responses.
public class VKJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
public static VKJsonTokenExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Instagram-specific token extractor for Instagram API token responses.
public class InstagramAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {
public static InstagramAccessTokenJsonExtractor instance();
public OAuth2AccessToken extract(Response response) throws IOException;
}Google-specific device authorization extractor for Google's device flow.
public class GoogleDeviceAuthorizationJsonExtractor extends DeviceAuthorizationJsonExtractor {
public static GoogleDeviceAuthorizationJsonExtractor instance();
public DeviceAuthorization extract(Response response) throws IOException;
}Extracts Google device authorization response:
{
"device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
"user_code": "GQVQ-JKEC",
"expires_in": 1800,
"interval": 5,
"verification_url": "https://www.google.com/device"
}Base class for OAuth 2.0 JSON token extractors.
public abstract class OAuth2AccessTokenJsonExtractor implements TokenExtractor<OAuth2AccessToken> {
protected static final ObjectMapper OBJECT_MAPPER; // Jackson ObjectMapper
public OAuth2AccessToken extract(Response response) throws IOException;
public void generateError(Response response) throws IOException;
// Helper methods for subclasses
protected String extractRequiredParameter(JsonNode json, String parameter, Response response)
throws IOException;
protected String extractOptionalParameter(JsonNode json, String parameter);
protected Integer extractExpiresIn(JsonNode json);
}Base class for device authorization extractors.
public abstract class DeviceAuthorizationJsonExtractor {
public abstract DeviceAuthorization extract(Response response) throws IOException;
}Most extractors handle standard OAuth 2.0 error responses:
{
"error": "invalid_grant",
"error_description": "Authorization code has expired"
}Some extractors handle provider-specific error formats:
Facebook Errors:
try {
OAuth2AccessToken token = service.getAccessToken("code");
} catch (FacebookAccessTokenErrorResponse e) {
// Access Facebook-specific error information
String message = e.getMessage();
String type = e.getType(); // "OAuthException"
int code = e.getCode(); // 100
String traceId = e.getFbTraceId(); // "DtxvtGRaxbB"
}Token extractors are automatically used by their corresponding APIs:
// Token extractor is automatically selected based on API
OAuth20Service service = new ServiceBuilder("client_id")
.apiSecret("client_secret")
.build(FacebookApi.instance()); // Uses FacebookAccessTokenJsonExtractor
OAuth2AccessToken token = service.getAccessToken("code"); // Returns appropriate token type| Extractor Class | API | Token Type | Special Features |
|---|---|---|---|
FacebookAccessTokenJsonExtractor | FacebookApi | OAuth2AccessToken | Custom error handling |
SalesforceJsonTokenExtractor | SalesforceApi | SalesforceToken | Instance URL |
OpenIdJsonTokenExtractor | GoogleApi20 | OpenIdOAuth2AccessToken | JWT ID token, claims |
SlackJsonTokenExtractor | SlackApi | SlackOAuth2AccessToken | User access token |
FitBitJsonTokenExtractor | FitbitApi20 | FitBitOAuth2AccessToken | User ID |
PolarJsonTokenExtractor | PolarAPI | PolarOAuth2AccessToken | User ID, X-User-ID |
VKJsonTokenExtractor | VkontakteApi | OAuth2AccessToken | VK-specific format |
InstagramAccessTokenJsonExtractor | InstagramApi | OAuth2AccessToken | Instagram format |
GoogleDeviceAuthorizationJsonExtractor | GoogleApi20 | DeviceAuthorization | Device flow support |
To create a custom token extractor:
public class CustomTokenExtractor extends OAuth2AccessTokenJsonExtractor {
private static final CustomTokenExtractor INSTANCE = new CustomTokenExtractor();
public static CustomTokenExtractor instance() {
return INSTANCE;
}
@Override
public OAuth2AccessToken extract(Response response) throws IOException {
JsonNode json = OBJECT_MAPPER.readTree(response.getBody());
// Extract standard fields
String accessToken = extractRequiredParameter(json, "access_token", response);
String tokenType = extractOptionalParameter(json, "token_type");
Integer expiresIn = extractExpiresIn(json);
String refreshToken = extractOptionalParameter(json, "refresh_token");
String scope = extractOptionalParameter(json, "scope");
// Extract custom fields
String customField = extractOptionalParameter(json, "custom_field");
return new CustomToken(accessToken, tokenType, expiresIn, refreshToken,
scope, customField, response.getBody());
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-github-scribejava--scribejava-apis