Authentication
Discussion
The Stack Exchange API offers user authentication via OAuth 2.0, specifically templated after Facebook's implementation. There are two flows, an explicit grant for server side applications and an implicit one for pure browser based ones.
The explicit OAuth 2.0 flow consists of the following steps:
- Send a user to
https://stackoverflow.com/oauth
, with these query string parameters- client_id
- scope (details)
- redirect_uri - must be under an apps registered domain
- state - optional
- The user approves your app
- The user is redirected to redirect_uri, with these query string parameters
- code
- state - optional, only returned if provided in the first step
- POST (application/x-www-form-urlencoded) the following parameters to
https://stackoverflow.com/oauth/access_token
- client_id
- client_secret
- code - from the previous step
- redirect_uri - must be the same as the provided in the first step
This request is responded to with either an error (HTTP status code 400) or an access token of the form
access_token=...&expires=1234
.expires
will only be set if scope does not includeno_expiry
, the use of which is strongly advised against unless your app truly needs perpetual access.In order to get
access_token
andexpires
(if applicable) wrapped in a JSON object, POST tohttps://stackoverflow.com/oauth/access_token/json
instead.
The implicit OAuth 2.0 flow consists of the following steps:
- Open a new window at
https://stackoverflow.com/oauth/dialog
, with these query string parameters- client_id
- scope (details)
- redirect_uri - must be under an apps registered domain
- state - optional
- The user approves your app
- The user is redirected to redirect_uri, with these parameters in the hash
- access_token
- expires - optional, only if scope doesn't contain
no_expiry
The explicit flow should be used by server-side applications, with special care taken to never leak client_secret
.
Client side applications should use the implicit flow.
After you have authenticated a user once, regardless of flow, subsequent re-authorizations will occur without requiring user action. Naturally, should a user revoke an applications permissions then further action will be required to re-authorize.
Applications using the implicit flow can make use of our provided minimalistic JavaScript SDK.
Scope
With an empty scope
, authentication will only allow an application to identify a user via the /me method.
In order to access other information, different scope
values must be sent. Multiple values may be sent in scope
by
comma or space delimitting them.
- read_inbox - access a user's global inbox
- no_expiry - access_token's with this
scope
do not expire - write_access - perform write operations as a user 2.1
- private_info - access full history of a user's private actions on the site 2.1
Desktop Applications
Desktop applications cannot participate directly in OAuth 2.0 flows, however the embeddable browser controls available in most frameworks make it possible to work around this limitation.
Desktop applications should use the implicit client-side flow, hosting the process within a browser control. For redirect_uri, a value of
https://stackoverflow.com/oauth/login_success
should be used. Upon a successful authentication, access_token
will
be placed in the url hash as with a standard implicit authentication.
Usage
Access tokens can be passed (as access_token
) to any method to grant applications an increased throttle quota.
When passing an access token an app must pass its request key as well, if you don't have a request key you can obtain one by registering your application on Stack Apps.
Errors
OAuth 2.0 reports redirection errors in one of two ways: displaying an error page to the user, or redirecting to an application with the error
and error_description
parameters.
Which of these two occurs depends on what the exact error is. Any error that cast doubt on the application (for example, an unknown client_id
) causes the first case, all others cause the later case.
Note that the user rejecting an application is conceptually an error.
Possible errors are:
- invalid_request
- unauthorized_client
- access_denied
- unsupported_response_type
- invalid_scope
- server_error
- temporarily_unavailable
For the explicit flow, calls to /oauth/access_token
will respond with the same error codes, wrapped in a JSON object of the form
{ "error": { "type": "invalid_request", "message": "some reason" } }
Note that there is no guarantee that message
will be set.
Authenticating Applications
Some applications need the separate request quotas associated with authenticated users without actually having a notion of "users" to authenticate. This is most common on shared hosting solutions, such as Google App Engine, where many applications may share a single IP address.
Rather than using a separate authentication path for applications, an author of such an application should obtain (via a normal OAuth 2.0 flow) a no_expiry
token
under their own account for the exclusive use of their application.
Unregistered Users
The Stack Exchange sites make it easy for users to participate without registering, however to authenticate with the API a user must be registered. This is driven by both technical concerns and philosophical ones.
Technically, there's no easy way to identify unregistered users while operating under the stackexchange.com domain. The most obvious work around, making authentication site-centric instead of network wide, would solve this it would make user's with accounts on multiple sites experience much worse. Other approaches, in the vein of global login, are rather brittle and difficult to guarantee will work with all auth flows.
Philosophically, there are methods which we want to provide to clients but also want to watch for abuse. In version 2.0, the /events method is an example. We want to provide this data, but we also want to be able to shut down scrapers who aren't following our attribution terms. Forcing abusive users to register to, well, abuse makes it easier to deal with them. It's easy to envision bits of the write API that will need similar protection.