Services¶
Note
This project has been cancelled, and this information is historical.
A Service provides server functionality beyond basic manipulation of resources.
Authentication¶
Several endpoint handle user authentication.
https://browsercompat.org/accounts/profile/ is an HTML page that summarizes the users’ account, which includes:
- The username, which can’t be changed.
- Changing or setting the password, which is optional if a linked account is used.
- Viewing, adding, and removing linked accounts, which are optional if a password is set. The support linked account type is Firefox Accounts.
- Viewing, adding, and removing emails. Emails can be verified (a link is clicked or a trusted linked account says it is verified), and one is the primary email used for communication.
Additional endpoints for authentication:
/accounts/
- Redirect to login or profile, depending on login state/accounts/signup/
- Create a new account, using username and password/accounts/login/
- Login to an existing account, using username and password or selecting a linked account/accounts/logout/
- Logout from site/accounts/password/change/
- Change an existing password/accounts/password/set/
- Set the password for an account using only a linked account/accounts/email/
- Manage associated email addresses/accounts/password/reset/
- Start a password reset via email/accounts/social/connections/
- Manage social accounts/accounts/fxa/login/
- Start a Firefox Accounts login
OAuth2 Authentication¶
A user can register an OAuth2 client application, and then use that application to provision bearer tokens on behalf of users. OAuth2 Simplified is a technical but gentle introduction to OAuth2. The OAuth2 website is a decent starting point for learning how OAuth 2.0 works and finding some (older) client libraries, and the OAuth2 specification has details on the protocols.
Back-End Applications¶
When the application is going to run on a server or a local machine, it is possible to keep a client secret secure, and authenticate the client to the server using this secret.
The steps are:
- Setup your OAuth2 Confidential Client Application
- Request an authorization code for your user
- Exchange the authorization code for an access token
- Use the access token to access the API
- Refresh the access token as needed
Setup Application¶
First, log into the API and go to your profile page (/accounts/profile/
,
linked under your username in the title bar).
Next, select “Apps” from the profile menu, going to /oauth2/applications/
.
Select “New Application”.
Fill in the form:
- Name - A descriptive name, or your website URL. This will be displayed to your users.
- Client ID - Keep the generated value
- Client secret - Keep the generate value
- Client type - Confidential
- Authorization grant type - Authorization code
- Redirect uris - One or more redirect URIs owned by your client application. This could be a localhost URI for development, and/or a URI on your deployed website.
Select Save.
Request Auth Code¶
When you need to make an authenticated request on behalf of a user, start the process by requesting an authorization code.
Redirect the user to the authorization endpoint (broken up to show query parameters):
https://browsercompat.org/oauth2/authorize/?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=REDIRECT_URI&
scope=read write
The user will login if they are not already logged in, and then asked if they
want to authorize your application. If they say yes, your redirect URI will
be called with the query string ?code=AUTHORIZATION_CODE
. If there was a
problem, including the user denying access, then the query string will be
?error=ERROR_TYPE
. See the Authorization Grant Error Response section in
the OAuth2 spec for possible error types.
Exchange for Token¶
So far, the communication has been over the internet in the user’s browser. The backend server communicates directly with the authorization server to exchange the authorization code for an access token. The authorization code is valid for a short time.
The backend server POST to this URL:
https://browsercompat.org/oauth2/token/
with this form-encoded content:
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
The authorization server will response with JSON:
{
"expires_in": 36000,
"token_type": "Bearer",
"access_token": "ACCESS_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"scope": "read write"
}
Access the API¶
When accessing the API on behalf of the user, include the access token in the
Authorization
header:
POST /api/v2/supports
Host: browsercompat.org
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
Authorization: Bearer ACCESS_TOKEN
{
"data": {
"type": "supports",
"relationships": {
"version": {
"data": {
"type": "versions",
"id": "4"
}
},
"feature": {
"data": {
"type": "features",
"id": "6"
}
}
}
}
}
The command line tool curl
can also be used. Let’s say you wanted to add
a note to the support with ID 1. If you place this JSON API request in a
file named “update.json”:
{
"data": {
"type": "supports",
"id": "1",
"attributes": {
"note": {
"en": "Added a note"
}
}
}
}
then this curl
command will update the API:
curl -v -X PATCH
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-d @update.json \
https://browsercompat.org/api/v2/supports/1
Invalid Tokens¶
The token can expire because the user revoked it (see the Token section of your profile in the API), or because the token expired. The access token has an expiration date of 36000 seconds (10 hours). When you try to use an invalid access token, you’ll get an authorization denied response:
HTTP/1.0 401 UNAUTHORIZED
Content-Type: application/vnd.api+json
WWW-Authenticate: Bearer realm="api"
{
"errors": [
{
"detail": "Authentication credentials were not provided.",
"status": "401"
}
]
}
Refresh the Token¶
If a token is not revoked, you can use the refresh token to provision a new access token. POST to the token URL again (https://browsercompat.org/oauth2/token/), with the form data:
grant_type=refresh_token&
refresh_token=REFRESH_TOKEN&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
The response is another access token response, with a fresh access token and a fresh refresh token. A token can also be refreshed before the access token expires.
Front-End or Mobile Applications¶
For a front-end application, all the code is in JavaScript, and any secret would be included in the source code downloaded to the user’s browser. Mobile applications, such as iPhone or Android applications, use compiled code, but any client secret would still have to be present in application code. Because of this, OAuth can’t be used directly with client secrets, and thus the client can’t authenticate itself to the server.
One way to retain authentication is to use an API proxy, where the application talks to a thin backend that handles the details of the OAuth2 protocol. See Alex Bilbie’s post, OAuth and Single Page JavaScript Web-Apps for a discussion of why this is a good idea, and a sketch of how to implement it.
Because the API does not expose user’s information, we allow the Implicit Grant authentication type, which does not authenticate the client, but relies on a predetermined client URL to accept tokens after user authentication.
The steps are:
- Setup your OAuth2 Public Client Application
- Request an access token for your user
- Use the access token to access the API
- Refresh the access token as needed
Setup Application¶
First, log into the API and go to your profile page (/accounts/profile/
,
linked under your username in the title bar).
Next, select “Apps” from the profile menu, going to /oauth2/applications/
.
Select “New Application”.
Fill in the form:
- Name - A descriptive name, or your website URL. This will be displayed to your users.
- Client ID - Keep the generated value
- Client secret - Keep the generate value
- Client type - Public
- Authorization grant type - Implicit
- Redirect uris - One or more redirect URIs owned by your client application. This could be a localhost URI for development, and/or a URI on your deployed website.
Select Save.
Request a Token¶
To request a access token, redirect the user to the authorization endpoint (broken up to show query parameters):
https://browsercompat.org/oauth2/authorize/?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=REDIRECT_URI&
scope=read write
The user will login if they are not already logged in, and then asked if they want to authorize your application. If they say yes, your redirect URI will be called with a long fragment string:
https://yoursite.com/redirect#
expires_in=36000&
state=&
token_type=Bearer&
access_token=ACCESS_TOKEN&
scope=read+write
Your code will proceess the fragment string to extract the access token.
If there is an error, you will get a response like:
https://yoursite.com/redirect#error=access_denied
See the Implicit Grant Error Response section in the OAuth2 spec for possible error types.
Using the Token¶
To use the access code, add an Authorization
header with the value
Bearer ACCES_TOKEN
. See Access The API in the back-end client section
for more details.
The token will eventually expire, and the API request will fail. See Invalid Tokens in the back-end client section for details. Implicitly granted tokens do not have an associated refresh token, and the user must return to the API to grant access again.
Data Browser¶
The Data Browser at https://browsercompat.herokuapp.com/browse/ is an Ember.js single-page app that allows browsing the resources currently available in the API. It is built with Ember libraries that work with JSON API RC1.
Importer¶
The MDN Importer at https://browsercompat.herokuapp.com/importer/ is used to scrape data from MDN, extract compatibility data, pinpoint data issues on MDN pages, and commit extracted data to the API.