Here are the different ways a client (application) can get an access token.

Note Update [03-July-2015]: hybris seems to have changed their Domain scheme. technoblog seems to be renamed to labs. Updated all links in this page from http://techblog.hybris.com to http://labs.hybris.com/

Authorization Code Flow (Server-Side Flow)

The standard flow.
A user is redirected to the authorization server (Drupal instance with oauth2_server installed), where he logs in, and is then presented with an authorization form (skipped if the client is configured to do so).
After authorization has been confirmed, the authorization server redirects back to the client with an authorization code.
The client then does an authorization_code request with his full client credentials (client key and client secret) as well as the received code, and is
given an access token (along with its expiry time and a refresh token).

To mitigate possible CSRF attacks, the oauth2_server module requests all authorization requests to have a state parameter, which is checked by the client at redirect_url to make sure that the request really came from the server. If the state doesn't validate / match, the client MUST discard the received token.
The oauth2_server tests use drupal tokens (drupal_get_token / drupal_valid_token) to generate values based on the site's private key, but any random value can be used.

Additional documentation: https://labs.hybris.com/2012/06/01/oauth2-authorization-code-flow/

Implicit Flow (Client-Side Flow)

The flow intended for pure-JS applications. Not usable from inside a server language like PHP.
A user is redirected to the authorization server (Drupal instance with oauth2_server installed), where he logs in, and is then presented with an authorization form (skipped if the client is configured to do so).
After authorization has been confirmed, the authorization server redirects back to the client with an access token.
As you can see, the difference here is that there is no authorization code and a future authorization_code grant request,
but instead an access token is immediately received.
This is because for JS apps an authorization_code grant makes no sense, since the client_secret would be exposed to the user.

The access token is received at the redirect_url through a special "hash" query string,
which ensures that it doesn't get passed to the server-side (a PHP script wouldn't be able to access it).

A possible security hole is described at: http://homakov.blogspot.com/2012/08/oauth2-one-accesstoken-to-rule-them-all.html
If your server has multiple clients, a JS app can't know that the token it just received was actually issued for itself, and not for another client (this is the problematic nature of unbounded access tokens in OAuth2).
Thus, the token must always be considered insecure, and the server side should validate it prior to using it for authentication by doing an authorized request to oauth2/tokens/$yourtoken.
The endpoint returns 404 if the token was not found or has expired.

Additional documentation: https://labs.hybris.com/2012/06/05/oauth2-the-implicit-flow-aka-as-the-client-side-flow/

A useful JS library for implementing the implicit flow and doing requests afterwards: https://github.com/andreassolberg/jso

Client credentials flow

There is no redirect to the server, a POST request is done directly to the "oauth2/token" endpoint with the client credentials,
and an access token is received. See the "Client credentials" grant type description for more information.

Resource owner password flow

There is no redirect to the server, a POST request is done directly to the "oauth2/token" endpoint with the user credentials,
and an access token is received. See the "Password" grant type description for more information.

Grant types

Grant types are different ways of granting an access token based on a POST request to the "oauth2/token" endpoint.

  • Authorization code
    Used to exchange an authorization code for an access token (and a refresh token).

    Additional documentation: https://labs.hybris.com/2012/06/01/oauth2-authorization-code-flow/

  • Refresh token
    Used to exchange expired access tokens for new ones, with the help of a refresh token.

    The access tokens issued are by default short lived (they expire after 1 hour).
    Hence, a refresh token with a longer lifetime (14 days) is also issued,
    allowing applications to exchange an expired access token for a new one, without redoing authorization.
    If the "always_issue_new_refresh_token" setting is true, a new refresh token is issued whenever an existing
    one has been used. This allows the client to always have a valid refresh token.
    Otherwise, once the refresh token expires, the authorization needs to be requested again.

    Additional documentation: https://labs.hybris.com/2012/06/05/oauth2-refreshing-an-expired-access-token/

  • Client credentials
    Used to authenticate the client (instead of asking for authorization from the user).
    In this case Services doesn't know who tho the current user is ($user->uid is 0).
    Usually used for administration tasks specific to the client.

    Additional documentation: https://labs.hybris.com/2012/07/09/oauth-the-client-credentials-flow/

  • Password
    Resembles a drupal login. Accepts a username and password, returns an access token.
    Additional documentation: https://labs.hybris.com/2012/06/11/oauth2-resource-owner-password-flow/

See the OAuth2 Server tests for examples of requests using drupal_http_request().