mainmatter / rails_api_auth

Lightweight Rails Engine that implements the "Resource Owner Password Credentials Grant" OAuth 2.0 flow as well as Facebook authentication
MIT License
139 stars 35 forks source link

OAuth access tokens should equal tokens returned by authenticating API #28

Open maletor opened 8 years ago

maletor commented 8 years ago

Unless there is something totally flawed with my logic, the last step of generating a new, separate access token is unnecessary where login is via OAuth.

It would be more powerful to forward the access tokens exactly as acquired back to the client. For a few reasons.

  1. Less tokens. We don't expect this app to have its own other client apps. A lean Rails API would have a separate resource server and authentication server. By sending a quick "verify token" request to Facebook we can assure its validity, should Facebook remove the user after the initial validation client side. Further, you could use JWT and do token verification with an air gap if you owned the authentication server and resource server.
  2. Access third party APIs directly from the client. Ember, for instance, beautifully sets up adapters for models. So consider we had a user model in our SPA and authenticated with a Facebook access token. We can make requests directly to the Graph API host for user info that never goes stale. Think about the power with an access token belonging to a large suite of centrally authorized microservices. Sideloading disparate objects becomes a non-issue so long as CORS is properly configured.
  3. Users not wanting to authenticate via OAuth with your client API can use Basic Auth at Facebook to get a token directly so that they may start using your API. Of course, the client API is still around to service requests for token generation but that's mostly a convenience. Either token generation method should be valid.

You might say that exposing the Facebook access token versus the client API's access token is less secure. In a worse case scenario situation where you have an XSS vulnerability the attack surface is larger by the difference between what your app does with the scopes granted and the total scopes granted. Again, if you owned the authentication and resource server this can be reduced to something really small.

You don't even have to store the access tokens in the database. They are simply checked real time (maybe cached, ideally JWT). Client side apps would support this setup too.

marcoow commented 8 years ago

The idea of this library is really more that you'd use Facebook, Google etc. as a means of validating the user's identity not to expose their access tokens directly to the client. What you usually want to have is multiple ways of authenticating users when they use your application - be it against your server directly via username/password or be it an external provider like Facebook etc. In any case you want users to end up with a token that's been issued by your application and can be used to e.g. look up the respective user in the DB.

maletor commented 8 years ago

That idea isn't excluded by what I suggested. I can imagine a user would send as many access tokens as the client is wanting to support. Maybe the user could even pass a hint in a custom header to speed up the process of validating it. On Fri, Mar 18, 2016 at 1:43 AM Marco Otte-Witte notifications@github.com wrote:

The idea of this library is really more that you'd use Facebook, Google etc. as a means of validating the user's identity not to expose their access tokens directly to the client. What you usually want to have is multiple ways of authenticating users when they use your application - be it against your server directly via username/password or be it an external provider like Facebook etc. In any case you want users to end up with a token that's been issued by your application and can be used to e.g. look up the respective user in the DB.

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/simplabs/rails_api_auth/issues/28#issuecomment-198257443

marcoow commented 8 years ago

Not sure what you mean. When you're using bearer token auth you can only send one bearer token in the Authorization header per request.

marcoow commented 8 years ago

@maletor: any update on this?

maletor commented 8 years ago

Yes, you can only send one, but that doesn't stop your server from validating it at more than one place.