-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Summary
Support multiple authentication methods in a single XDK Client instance, with automatic auth selection based on endpoint requirements.
Use Case
Applications that need both:
- Bearer Token (OAuth 2.0 App-Only): For read-only operations (Filtered Stream)
- OAuth 1.0a User Context: For write operations (posting tweets)
Currently requires maintaining two separate Client instances.
Current Behavior
When both credentials are provided to a single Client, XDK uses Bearer Token for all requests, causing HTTP 403 on endpoints that require OAuth 1.0a.
Example (fails):
const oauth1 = new OAuth1({
apiKey: process.env.X_API_KEY,
apiSecret: process.env.X_API_SECRET,
accessToken: process.env.X_ACCESS_TOKEN,
accessTokenSecret: process.env.X_ACCESS_TOKEN_SECRET
});
const client = new Client({
bearerToken: process.env.X_BEARER_TOKEN,
oauth1
});
await client.posts.create({ text: 'test' }); // ❌ HTTP 403Error: "Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint"
Requested Behavior
Auto-select appropriate authentication based on endpoint requirements:
const client = new Client({
bearerToken: process.env.X_BEARER_TOKEN, // For read operations
oauth1 // For write operations
});
// Auto-uses Bearer Token for streaming
const stream = await client.stream.posts({ ... });
// Auto-uses OAuth 1.0a for posting
await client.posts.create({ text: 'test' }); // ✅ SUCCESSTest Cases (attached)
test-dual-credentials.js- Fails with HTTP 403test-oauth-only.js- Works (proves OAuth 1.0a signature fix in v0.1.2-beta)
Implementation Suggestions
Option 1: Endpoint-based routing
Auto-select auth based on endpoint requirements (similar to how X API already enforces auth server-side):
const client = new Client({
bearerToken: process.env.X_BEARER_TOKEN,
oauth1
});
// XDK internally knows POST /2/tweets requires OAuth 1.0a
await client.posts.create({ text: 'test' }); // ✅ Uses oauth1
// XDK knows GET /2/tweets/search/stream accepts Bearer Token
const stream = await client.stream.posts(); // ✅ Uses bearerTokenRationale: Since X API already has defined auth requirements for each endpoint, XDK could mirror this mapping internally. This would let developers use the client naturally without needing to specify auth explicitly.
Option 2: Explicit auth parameter
Developers specify which auth to use per call:
await client.posts.create({ text: 'test' }, { auth: 'oauth1' });
await client.stream.posts({ auth: 'bearer' });Rationale: More explicit control, though requires developers to know auth requirements for each endpoint.
Option 3: Separate method namespaces
Different namespaces for different auth types:
client.read.stream.posts({ ... }); // Uses Bearer Token
client.write.posts.create({ ... }); // Uses OAuth 1.0aRationale: Clear separation, possibly larger API redesign.