Since the Users plugin has a secure way1 to authorize access to a Snap! system via a browser, offering such an access via OAuth2 is a very easy to implement extension.
The concept is very simple. Applications that want to access our services can do so using special URLs. However, anything that require the user to have permission generally necessitate a user to be logged in. Therefore an application that wants to manipulate data also needs to be logged in.
The application will make use of the Snap-Authorize HTTP field as follows:
GET /user/oauth2 HTTP/1.1 Snap-Authorization: Snap (base64 of "<username>:<password>")
The result is a reply with the authorization cookie, a session identifier in the form of XML content. We use XML for the content because Snap! uses XML for most of its documents when handling data. Although we may later default to JSON since RFC 6749 (OAuth 2.0) uses JSON exclusively. You may already request JSON by setting an Accept in your header with "application/json" as the value. The result is similar, only in JSON instead of XML.
<?xml version="1.0"?> <snap> <oauth2-session>session-id</oauth2-session> <result>success</result> </snap>
All the following accesses to the server can make use of the secret code as a bearer authentication as in:
GET /some/url HTTP/1.1 Snap-Authorization: Bearer <session-id>
Note that other fields and a body may be required depending on what you are trying to access on the server.
When the Snap-Authorization field is missing and the system knows the URI is from an API, the server replies with the following field instead of redirecting the user to the /login page:
WWW-Snap-Authorization: Snap realm="Snap OAuth2"
This reply does include double quotes around the realm name. Since this is not to be shown to end users, the realm cannot be changed. We may add other fields later.
The reason for using the name "Snap-Authorization" instead of just plain "Authorization" is because Apache2 does not pass the "Authorization" field to CGI processes. In future versions, those that will not make use of Apache2, will certainly support both fields.
The Global OAuth2 feature is already functional and can be used to implement tools that manage the site remotely (without a browser) although just with OAuth2 the external application has to deal with HTML.
The OAuth2 implementation should probably better follow RFC 6749, although it is not yet an official reference, it is not unlikely that more products will offer libraries that expect those exact client/server messages.