Skip to content

Feature Request: Multi-Auth Support in Single XDK Client #14

@parkertoddbrooks

Description

@parkertoddbrooks

test-dual-credentials.js

test-oauth-only.js

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 403

Error: "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' });  // ✅ SUCCESS

Test Cases (attached)

  • test-dual-credentials.js - Fails with HTTP 403
  • test-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 bearerToken

Rationale: 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.0a

Rationale: Clear separation, possibly larger API redesign.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions