OAuth2 best practice

Lately I have been playing around with the OGS API, trying to implement a chrome extension. After a while I managed to get some results, but now I’m wondering about the best way to use OAuth2.

My understanding of the required workflow
First I would like to claryfy the worflow around token generation. At the moment, I’m requesting a new token each time the extension is loaded. I’m sure this is really really bad for many reasons (load on the server, infringes the “do not store user password” rule…) Since the documentation is not clear enough for me, could you please tell me if my understanding is correct about the process:

  1. ask user for its username/password and do not store the pass
  2. request token using client_id, client_secret, “password”, username, user_password
  3. store the response
  4. use response.access_token as long as it’s valid
  5. when token is not valid anymore, request new token using
    client_id, client_secret, “refresh_token”, username, response.refresh_token

If I’m right, this leads to more questions.

Token lifespan
How long is the token available ? I see there is a “expires_in’” field on the response corresponding to 1 year expressed in second. Does that mean I can use the token for a full year with no restriction ?
And how do I know the token is expired ? Do I just get the “401: Invalid token” error or is it something different ?

Sharing client_secret
The doc says client_id, client_secret should never be shared, which is understandable.
But a chrome extension is no more than a bunch of text files zipped together, so anyone can see the content quite easily.
Let’s imagine my extension is a success and I want to share it on the google extension store. Does that mean I have to share it with no client_id client_secret and ask my users to generate one ?
It would mean for a new user:

  • download and install the extension
  • go to http://online-go.com/user/settings to generate an app specific password
  • go to http://online-go.com/developer to generate client_id/client_secret pair
  • copy paste all these hexa chars to a setting page on my extension
    I think many users would find it quite a boring process just to get a new icon on their favorite browser.

One last question
I was also wondering about the need of having a client_id / client_secret pair, since they are sent together and never used again… Is it something like a work in progress ?

That’s it. Sorry for the length of this post, but I really hope you will be able to answer my questions so that I can create the perfect chrome extension :smiley:

2 Likes

Hi guishu,

Your understanding of the token workflow is correct. In particular, you must not store user passwords. This is why a lot of OAuth2 services work by showing you the login page in a browser - the client should not even be responsible for reading the username and password, since that can be delegated to the auth server.

According to spec, if you submit an expired token, the response will be an invalid token response. The token will be valid for the period described in expires_in unless the end user revokes the grant. If you try to refresh the token when the grant is revoked, you should receive an invalid_grant error. In other words, if you get a 401, try to refresh, if it fails, then you need to go through the login-flow again from the beginning. The server MAY include some additional error data in either the error_uri or error_description field, but I don’t know if OGS does this.

Regarding the client id/secret pair, you’re also correct. The client credentials are per-application, not per-user. They can be used to disable rogue apps, or implement throttling, for example.

Client secrets are explicitly an optional feature of OAuth2 because you can’t keep them secret if you’re distributing your app. This is equally true for compiled binaries as it is for chrome extensions. Client secrets are mostly intended for server->server flows where both endpoints are trustworthy. For a chrome extension or installed application, they’re useless.

They’re intended to authenticate the client application. In my day job we use them on password flows for command line tooling, but use registered callback URIs for distributed apps.

I’d really like to see a proper redirect-flow for OGS since it obviates the requirement for distributing secrets, and for the client to ever receive user credentials, but I’m an OAuth 2 geek.

So you mean I can share the extension with my client_id/secret ? That’s what I intended anyway :stuck_out_tongue:

Thanks for these clarifications, I’ll see what I can produce from them

The problem is that if someone wants to make trouble for you, he can just steal your client_id/secret and start making requests on your behalf, with the result that @matburt will turn off your OAuth2 client, but there’s not a huge amount that you can do about that… it’s just the usual mess that is internet security.

This doesn’t perfectly answer everyone’s concerns but wee actually have a mechanism in place to perform 3-legged oauth:

http://tools.ietf.org/html/rfc6749#section-4.1.1

However… there are some other technical concerns that we have to address there and the oauth2 section of our site needs more work in order to deal with it. I suspect it’ll be another few months before I have a chance to circle back around and address them.

In the meantime I’d just ask that developers take as much precaution as they can regarding the visibility of their client id and secret. Obviously right now you’d have to include both of these with your app and at the moment that’s the best you can do until I can provide you with more options.

Oh, that’s awesome news @matburt. Looking forward to seeing it, if I can help out at all, I’d be more than happy.