0
# Token Extractors
1
2
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.
3
4
## Capabilities
5
6
### Facebook Access Token Extractor
7
8
Facebook-specific token extractor that handles Facebook's non-standard error response format.
9
10
```java { .api }
11
public class FacebookAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {
12
public static FacebookAccessTokenJsonExtractor instance();
13
14
// Inherited from OAuth2AccessTokenJsonExtractor
15
public OAuth2AccessToken extract(Response response) throws IOException;
16
17
// Facebook-specific error handling
18
public void generateError(Response response) throws IOException;
19
}
20
```
21
22
Facebook returns errors in a non-standard format with specific error structure:
23
```json
24
{
25
"error": {
26
"message": "This authorization code has been used.",
27
"type": "OAuthException",
28
"code": 100,
29
"fbtrace_id": "DtxvtGRaxbB"
30
}
31
}
32
```
33
34
**Usage Example:**
35
```java
36
// Automatically used by FacebookApi
37
OAuth20Service service = new ServiceBuilder("app_id")
38
.apiSecret("app_secret")
39
.build(FacebookApi.instance());
40
41
try {
42
OAuth2AccessToken token = service.getAccessToken("invalid_code");
43
} catch (FacebookAccessTokenErrorResponse e) {
44
System.out.println("Facebook Error: " + e.getMessage());
45
System.out.println("Error Type: " + e.getType());
46
System.out.println("Error Code: " + e.getCode());
47
System.out.println("Trace ID: " + e.getFbTraceId());
48
}
49
```
50
51
### Salesforce JSON Token Extractor
52
53
Salesforce-specific token extractor that creates `SalesforceToken` objects with additional Salesforce metadata.
54
55
```java { .api }
56
public class SalesforceJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
57
public static SalesforceJsonTokenExtractor instance();
58
59
public OAuth2AccessToken extract(Response response) throws IOException;
60
}
61
```
62
63
Extracts Salesforce-specific fields from token response:
64
```json
65
{
66
"access_token": "00Dxx0000000000!...",
67
"instance_url": "https://mycompany.salesforce.com",
68
"id": "https://login.salesforce.com/id/00Dxx.../005xx...",
69
"token_type": "Bearer",
70
"issued_at": "1234567890",
71
"signature": "base64signature"
72
}
73
```
74
75
### OpenID JSON Token Extractor
76
77
OpenID Connect token extractor that creates `OpenIdOAuth2AccessToken` objects with ID token and claims.
78
79
```java { .api }
80
public class OpenIdJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
81
public static OpenIdJsonTokenExtractor instance();
82
83
public OAuth2AccessToken extract(Response response) throws IOException;
84
}
85
```
86
87
Extracts OpenID Connect ID token and decodes JWT claims:
88
```json
89
{
90
"access_token": "ya29.a0...",
91
"expires_in": 3599,
92
"refresh_token": "1//0...",
93
"scope": "openid profile email",
94
"token_type": "Bearer",
95
"id_token": "eyJhbGciOiJSUzI1NiIs..."
96
}
97
```
98
99
### Slack JSON Token Extractor
100
101
Slack-specific token extractor that creates `SlackOAuth2AccessToken` objects with user access token information.
102
103
```java { .api }
104
public class SlackJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
105
public static SlackJsonTokenExtractor instance();
106
107
public OAuth2AccessToken extract(Response response) throws IOException;
108
}
109
```
110
111
Extracts Slack-specific fields from token response:
112
```json
113
{
114
"ok": true,
115
"access_token": "xoxb-...",
116
"token_type": "bearer",
117
"scope": "channels:read,users:read",
118
"authed_user": {
119
"access_token": "xoxp-..."
120
}
121
}
122
```
123
124
### Fitbit JSON Token Extractor
125
126
Fitbit-specific token extractor that creates `FitBitOAuth2AccessToken` objects with user ID.
127
128
```java { .api }
129
public class FitBitJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
130
public static FitBitJsonTokenExtractor instance();
131
132
public OAuth2AccessToken extract(Response response) throws IOException;
133
}
134
```
135
136
Extracts Fitbit user ID from token response:
137
```json
138
{
139
"access_token": "eyJhbGci...",
140
"expires_in": 28800,
141
"refresh_token": "c6a3...",
142
"scope": "activity heartrate location nutrition profile settings sleep social weight",
143
"token_type": "Bearer",
144
"user_id": "26FWFL"
145
}
146
```
147
148
### Polar JSON Token Extractor
149
150
Polar-specific token extractor that creates `PolarOAuth2AccessToken` objects with user IDs.
151
152
```java { .api }
153
public class PolarJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
154
public static PolarJsonTokenExtractor instance();
155
156
public OAuth2AccessToken extract(Response response) throws IOException;
157
}
158
```
159
160
Extracts Polar user information from token response:
161
```json
162
{
163
"access_token": "8fdf2a...",
164
"token_type": "bearer",
165
"x_user_id": 1234567,
166
"user_id": 1234567
167
}
168
```
169
170
### VKontakte JSON Token Extractor
171
172
VKontakte-specific token extractor for Russian social network token responses.
173
174
```java { .api }
175
public class VKJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
176
public static VKJsonTokenExtractor instance();
177
178
public OAuth2AccessToken extract(Response response) throws IOException;
179
}
180
```
181
182
### Instagram Access Token Extractor
183
184
Instagram-specific token extractor for Instagram API token responses.
185
186
```java { .api }
187
public class InstagramAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {
188
public static InstagramAccessTokenJsonExtractor instance();
189
190
public OAuth2AccessToken extract(Response response) throws IOException;
191
}
192
```
193
194
### Google Device Authorization Extractor
195
196
Google-specific device authorization extractor for Google's device flow.
197
198
```java { .api }
199
public class GoogleDeviceAuthorizationJsonExtractor extends DeviceAuthorizationJsonExtractor {
200
public static GoogleDeviceAuthorizationJsonExtractor instance();
201
202
public DeviceAuthorization extract(Response response) throws IOException;
203
}
204
```
205
206
Extracts Google device authorization response:
207
```json
208
{
209
"device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
210
"user_code": "GQVQ-JKEC",
211
"expires_in": 1800,
212
"interval": 5,
213
"verification_url": "https://www.google.com/device"
214
}
215
```
216
217
## Base Classes
218
219
### OAuth2AccessTokenJsonExtractor
220
221
Base class for OAuth 2.0 JSON token extractors.
222
223
```java { .api }
224
public abstract class OAuth2AccessTokenJsonExtractor implements TokenExtractor<OAuth2AccessToken> {
225
protected static final ObjectMapper OBJECT_MAPPER; // Jackson ObjectMapper
226
227
public OAuth2AccessToken extract(Response response) throws IOException;
228
public void generateError(Response response) throws IOException;
229
230
// Helper methods for subclasses
231
protected String extractRequiredParameter(JsonNode json, String parameter, Response response)
232
throws IOException;
233
protected String extractOptionalParameter(JsonNode json, String parameter);
234
protected Integer extractExpiresIn(JsonNode json);
235
}
236
```
237
238
### DeviceAuthorizationJsonExtractor
239
240
Base class for device authorization extractors.
241
242
```java { .api }
243
public abstract class DeviceAuthorizationJsonExtractor {
244
public abstract DeviceAuthorization extract(Response response) throws IOException;
245
}
246
```
247
248
## Error Handling
249
250
### Standard OAuth 2.0 Errors
251
Most extractors handle standard OAuth 2.0 error responses:
252
```json
253
{
254
"error": "invalid_grant",
255
"error_description": "Authorization code has expired"
256
}
257
```
258
259
### Provider-Specific Errors
260
Some extractors handle provider-specific error formats:
261
262
**Facebook Errors:**
263
```java
264
try {
265
OAuth2AccessToken token = service.getAccessToken("code");
266
} catch (FacebookAccessTokenErrorResponse e) {
267
// Access Facebook-specific error information
268
String message = e.getMessage();
269
String type = e.getType(); // "OAuthException"
270
int code = e.getCode(); // 100
271
String traceId = e.getFbTraceId(); // "DtxvtGRaxbB"
272
}
273
```
274
275
## Automatic Usage
276
277
Token extractors are automatically used by their corresponding APIs:
278
279
```java
280
// Token extractor is automatically selected based on API
281
OAuth20Service service = new ServiceBuilder("client_id")
282
.apiSecret("client_secret")
283
.build(FacebookApi.instance()); // Uses FacebookAccessTokenJsonExtractor
284
285
OAuth2AccessToken token = service.getAccessToken("code"); // Returns appropriate token type
286
```
287
288
## Complete Extractor List
289
290
| Extractor Class | API | Token Type | Special Features |
291
|----------------|-----|------------|------------------|
292
| `FacebookAccessTokenJsonExtractor` | `FacebookApi` | `OAuth2AccessToken` | Custom error handling |
293
| `SalesforceJsonTokenExtractor` | `SalesforceApi` | `SalesforceToken` | Instance URL |
294
| `OpenIdJsonTokenExtractor` | `GoogleApi20` | `OpenIdOAuth2AccessToken` | JWT ID token, claims |
295
| `SlackJsonTokenExtractor` | `SlackApi` | `SlackOAuth2AccessToken` | User access token |
296
| `FitBitJsonTokenExtractor` | `FitbitApi20` | `FitBitOAuth2AccessToken` | User ID |
297
| `PolarJsonTokenExtractor` | `PolarAPI` | `PolarOAuth2AccessToken` | User ID, X-User-ID |
298
| `VKJsonTokenExtractor` | `VkontakteApi` | `OAuth2AccessToken` | VK-specific format |
299
| `InstagramAccessTokenJsonExtractor` | `InstagramApi` | `OAuth2AccessToken` | Instagram format |
300
| `GoogleDeviceAuthorizationJsonExtractor` | `GoogleApi20` | `DeviceAuthorization` | Device flow support |
301
302
## Custom Extractor Implementation
303
304
To create a custom token extractor:
305
306
```java
307
public class CustomTokenExtractor extends OAuth2AccessTokenJsonExtractor {
308
private static final CustomTokenExtractor INSTANCE = new CustomTokenExtractor();
309
310
public static CustomTokenExtractor instance() {
311
return INSTANCE;
312
}
313
314
@Override
315
public OAuth2AccessToken extract(Response response) throws IOException {
316
JsonNode json = OBJECT_MAPPER.readTree(response.getBody());
317
318
// Extract standard fields
319
String accessToken = extractRequiredParameter(json, "access_token", response);
320
String tokenType = extractOptionalParameter(json, "token_type");
321
Integer expiresIn = extractExpiresIn(json);
322
String refreshToken = extractOptionalParameter(json, "refresh_token");
323
String scope = extractOptionalParameter(json, "scope");
324
325
// Extract custom fields
326
String customField = extractOptionalParameter(json, "custom_field");
327
328
return new CustomToken(accessToken, tokenType, expiresIn, refreshToken,
329
scope, customField, response.getBody());
330
}
331
}
332
```