Hello,
First, I would like to apologize for my english. I’m not a native speaker.
Background story :
I’m actually working on an API which uses Rails API. That API will serve a logic that a front-end team is going to consume within a Backbone.js application. Yes, we’re planning to eat our own dog food.
First, I started to play on a proof of concept API, which simply used Rails API, AMS, Devise and Mongoid. Users were created via Devise and they were doing requests on the API with their Devise authentication token.
Now, I would like to introduce an OAuth2 provider, which is built on Doorkeeper’s OAuth2 implementation. However I don’t want to install the provider on the same server than the API and I don’t want to play with too many tokens (Devise, Doorkeeper). That’s why I’m actually trying to find a way to avoid that.
By default Doorkeeper creates three collections on MongoDB :
- oauth_access_tokens
- oauth_access_grants
- oauth_applications
On the same MongoDB server I have an users collection. In the User Mongoid model (API side) I added a relationship to the Doorkeeper’s AccessTokens collection.
To sum up, my current architecture looks like that :
- An OAuth 2 Provider (Doorkeeper) with an access to MongoDB server XYZ.
- API app : Rails-API + Warden with an access to the same MongoDB server XYZ. That API will be a registered application (with a client_id and secret) on the OAuth provider.
- A web app built with Backbone.js
I have some issues to consider all the aspects of the ‘eating your own dog food’ philosophy in such a case.
At the moment, I have something which looks like that :
When an user wants to register a new account
- On the webapp, the user enters its credentials (username + password).
- Webapp will make a call on API with these credentials.
- API will create an user on MongoDB and generate an access token for Doorkeeper with an OAuth2 call using the Resource Owner Password Flow of OAuth2 :
RestClient.post(“#{APP_CONFIG[‘doorkeeper_app_url’]}/oauth/token”,
grant_type: “password”,
client_id: APP_CONFIG[‘doorkeeper_app_id’],
client_secret: APP_CONFIG[‘doorkeeper_app_secret’],
username: params[‘email’],
password: params[‘password’])
That call on Doorkeeper will first authenticate the user AND generate an access token.
- Then API returns token informations to the webapp. My webapp uses the token to make calls on API.
- API authenticates the user from the token on each received call. I don’t use session, this is a stateless API.
**When an user wants to sign in **
- Webapp sends credentials to the API.
- The API will authenticate the user directly from DB.
Issues and questions
As my webapp only sends credentials to the API which is a proxy to the OAuth2 provider, how am I sure that users will not abuse my API through the webapp flow ? Should I configure a rate-limit system on my own API OAuth2 application ? Or should I totally rebuild the current architecture/OAuth strategy ? Or maybe should I just add an additional security token ?
Thank you.