I have a website and an API. The website allows anonymous people to browse the catalogue, but you must be logged in to post stuff.
I have built an API that exposes the same functionality. The API is used by a mobile app we are developing, but we are also going to allow other developers to use the API (i.e. it's publicly documented). The entire API is currently requires OAuth (2.0) authentication. To prevent abuse we use rate-limiting per OAuth client-id/user-id combination.
Now a new requirement for the mobile app has come down: The app should allow anonymous users to browse our catalogue. I am not sure how to implement this, without opening up our API to abuse.
Anonymous OAuth access
The first problem is allowing anonymous access. If we still want the entire API protected by OAuth then our mobile app will have to use the client-credentials grant type (posting a client-id and secret key). But we would have to store the client-id and secret in the app itself. This is not secure since it can easily be reverse engineered.
Alternatively, we could use dynamic client registration. As soon as an app is installed, it registers with an (undocumented) API to create an OAuth client for itself. Problem here is, how do I protect the client registration endpoint? A secret key again? Plus, this leads to a large amount of OAuth clients registered.
Remove OAuth from public endpoints
Alternatively, we could remove OAuth from the public endpoints all together (i.e. browsing the catalogue) and only require OAuth for posting stuff or managing an account. But how would I protect the API from abuse then? Without OAuth I cannot rate-limit based on client-id.
I am not sure that rate-limiting based on IP address would work. We expect many mobile app users and I fear that crappy (Moroccan) mobile telecom providers are NAT-ing a large amount of phone users behind just a few IP addresses. This would quickly exhaust any rate-limit that we set.
Is this correct? Or can I safely rate-limit on IP address for mobile users?
Alternative security mechanism
I could also implement a different authentication mechanism alongside OAuth. Something that allows our mobile phone app access to the API, which can distinguish (and rate-limit) different phones/users but which is safe from people just extracting a shared secret key from our mobile app binary.
Any suggestions on how to allow anonymous access to my API but still rate-limit effectively?