twitchdev / issues

Issue tracker for third party developers.
Apache License 2.0
73 stars 6 forks source link

Conflicting rate limit counters between authorization methods #571

Open tje opened 2 years ago

tje commented 2 years ago

Brief description

Rate limits appear to be clashing between some endpoints when alternating between authorization methods. I've observed this with the new Get Extension Live Channels route in particular, with and without an app access token.

How to reproduce

  1. With an empty bucket, make a request to the public extension live channels route providing only a client ID:
GET https://api.twitch.tv/helix/extensions/live?extension_id=<client_id>
Client-Id: <client_id>
---
ratelimit-limit: 30
ratelimit-remaining: 29
  1. Quickly make a subsequent request, passing an app access token in the request headers:
GET https://api.twitch.tv/helix/extensions/live?extension_id=<client_id>
Client-Id: <client_id>
Authorization: Bearer <app_access_token>
---
ratelimit-limit: 800
ratelimit-remaining: 28

Sending these requests in the reverse order also returns odd results - 799/800 and 798/30. The remaining allotment appears to shared, determined by whichever method comes first following a clean slate.

I tried reaching out to different routes - /helix/extensions/live first, then /helix/users with a token - the shallow rate limit from the former carried over there as well

I also tried hammering the API with a token (sorry!) to see if this actually imposed any functional impact, and sure enough I hit the 800 ceiling after sending 29 more requests.

Expected behavior

I'd expect these two cases to carry independent counters, and for unauthenticated requests not to incur rate limiting points against the app.

Additional context or questions

I haven't tested any other routes aside from the couple mentioned above, so I'm not sure if this is specific to that "get extension live channels" endpoint.

BarryCarlyon commented 2 years ago

With an empty bucket, make a request to the public extension live channels route providing only a client ID:

This is an invalid example!

Get Extension Live Channels as used requrieds an oAuth token, as does ALL of helix.

However there are some legacy client ID's (mainly extensions) which have "no token" access to the API due to push back on the "you must use tokens to access the API". This led to the introduction of the helixToken (after a long while) for extensions to access to API in the front end - Using the Twitch API in an Extension Front End

So, no one should actually be calling the API with only a clientID and the problem may stem from the use of a older/legacy clientID to access the API without an oAuth token in the first place. Since an oAuth token is required and you tried to call it without an oAuth token. So an invalid test for what/how you should be calling the API in the first place.

As to why you get the helixToken rate (when calling with no token) and then are stuck with the helixToken rate when using a token (assuming same clientID) I'm not sure. So next test would be to test the API as documented to see if the problem persists when moving from a helixToken to a real token but why in production you would do that in the first place I don't know. And not a thing I have observed when I pass helixToken to my server to use for user lookups. Where the same server is also using an app access token to other calls. (Granted helixToken I use with the users API and the app access token any number of other endpoints)

TLDR: it's a bad test because you used behaviour that is not supported/documented in your first step when testing.

And the other scenario (helixToken to app access token) I have not observed this problem of a broken rate limit scenario.

tje commented 2 years ago

Dang, you're right, I tried to be so thorough but still totally glossed over the big authorization requirement text there. I was hastily cycling out the last few v5 endpoints I was using and assumed it was fine when it "just worked" after swapping out the URL. The old endpoint doesn't require authentication

However there are some legacy client ID's (mainly extensions) which have "no token" access to the API due to push back on the "you must use tokens to access the API".

This is confusing. I was using an extension, and I just tested it with a different newer-ish client ID but haven't been able to reproduce it. Also tried it with user and app access tokens and it looks like it's working as expected

Perhaps it isn't a problem with the Twitch API, but rather my extension is too old and dusty? I'm able to consistently reproduce the first "bad test" without providing a token at all with this particular client ID - do you know if there's any way I can "upgrade" it? Can I stuff cucumbers in its eyes to make it young and cool again or am I stuck with having to republish under a new app registration?

BarryCarlyon commented 2 years ago

do you know if there's any way I can "upgrade" it?

To my knowldge. no.

At some point Twitch will jsut kill this behaviour.

If you don't have an oAuth token then the old rate limit pool/logic was by "Client-ID/IP Pair" so if someone tries to abuse your ClientID, then shouldn't be able to effect your normal API calls. (From your server/another IP)

tje commented 2 years ago

If you don't have an oAuth token then the old rate limit pool/logic was by "Client-ID/IP Pair" so if someone tries to abuse your ClientID, then shouldn't be able to effect your normal API calls. (From your server/another IP)

This is what I would have expected, but I don't know if it's actually separated this way currently - I discovered this initially because my production service started throwing warnings about these rate limits while I was testing that unauthenticated API on my local machine


Also quick amendment to something I said earlier:

I just tested it with a different newer-ish client ID but haven't been able to reproduce it

Figured that "newer-ish" client ID was a bad example since it isn't published, but I don't have any other published ones anyways. Started poking around the extensions directory picking random IDs to test, and I'm able to hit the same API endpoint without a token for a lot of the older more established extensions. Not really surprising now, but I can see their current rate limit/position in the response headers which seems mildly concerning if it can be influenced without a token