End uses connect to scopes via the webAppOS scopes-related API function <request_scopes>, which takes a scopes driver name as the first argument. The <request_scopes> function is always called from the client side, since scopes authentication requires user intervention (e.g., to enter a password in a third-party window and to allow webAppOS to access user's data located at the third-party's server).
Drivers are usually named by an identifier ending with "_scopes", e.g., "webappos_scopes" or "google_scopes". The scopes driver must be accessible as a webAppOS service (or serverless service) via /services/[driver_name]/[driver_name]_driver.js (e.g., "/services/webappos_scopes/webappos_scopes_driver.js").
Besides statically hosted .js files, a driver can also serve AJAX requests at the URL path "/services/[driver_name]/" for internal purposes (e.g., to send tokens to the server for performing server-side validation of tokens).
The [driver_name]_driver.js must define an asynchronous (AMD) module implementing 2 functions:
define(function(){
var ...; // private properties
return {
request_access: async function(scopes, serverless_only) {
...
},
revoke_serverless_access: async function() {
...
}
};
})
Below we provide more explanations of what these functions must do.
async function request_access( |
| ) |
The main function for authenticating the desired scopes (e.g., to gain access tokens for remote cloud drives, which can be later mounted into the user's home directory).
The function must resolve successfully, if the given scope has been already authenticated earlier.
scopes | contains a space-delimited names of desired provider-specific scopes |
serverless_only | whether the driver must not try to store server-side tokens for offline access |
options | an optional parameter that can contain any additional provider-specific options; in case the scopes driver allows multiple accounts to sign in, options can contain the account name to authenticate |
Depending on the value of the serverless_only argument and other considerations, the driver can choose to perform either server-side, or serverless authentication.
For the server-side authentication, the function should perform certain browser-side authentication steps first (e.g., display a login window or redirect to a login page). Then it should inform the server about successful authentication (e.g., by redirecting to certain server-side servlet and sending some token). The server can perform additional authentication steps (e.g., token validation and obtaining access and refresh tokens for offline scope access). Additional servlet paths can be served for that (e.g., as URLs for OAuth2 callbacks).
Server-side offline/refresh tokens must be stored under the "xusers/[login]/[driver_name]" registry branch. The keys of that branch are some driver-specific IDs. Each value is a JSON object with the stored token/tokens along with the "description" and "on_release" properties. The latter specifies the web call action that has be called when the corresponding scope is to be released (and the offline tokens have to be revoked).
The web call action has to be provided by the driver and must have modifiers "private static jsoncall" (see The .webcalls File Format).
The value of the sample key "xusers/some_login/google_scopes" could be:
{
"user.profile": {
"description": "Google profile and drive for user1@gmail.com",
"access_token": "1234",
"refresh_token": "5678",
"on_release": "google_scopes.on_release"
},
"spreadsheets": {
"description": "Google spreadsheet for user2@gmail.com",
"access_token": "ABCD",
"refresh_token": "EFGH",
"on_release": "google_scopes.on_release"
}
}
The webappos.listAuthenticatedScopes web call can be used to list the server-side authenticated scopes IDs and their descriptions (while not revealing the tokens!). The webappos.releaseScope web call can be used to release the given scope and revoke its tokens.
Server-side tokens stored in the "xusers" registry branch as explained above, will remain valid after the user signs out. Thus, the corresponding scopes will be available for the next time the user signs in.
For serverless authentication, if the desired scopes have not been authenticated yet, the request_access function can either show a login page, or redirect to an external login page (preferrably, returning back after successful authentication).
The authentication process may require certain per-developer credentials (such as a client id or an API key), which can be stored in text files in the driver's folder (instructions on how to obtain the credentials can be displayed, if the files do not exist). Notice that if the credentials are stored in the driver's folder, they become publicly available, thus, someone can misuse them.
After succesfully authenticating the scopes, the request_access function can use any browser-side storage (e.g., cookies, localStorage, or JavaScript variables) to store the received tokens. The tokens can also be stored in the user registry branch. Unlike server-side keys, such browser-side registry keys are optional, since all serverless tokens will be revoked on sign out.
We advice to associate stored tokens with the corresponding remote account, however, certain third-parties can store tokens in cookies, thus, allowing just one authenticated account at a time.
a function for releasing and cleaning up all provider-specific browser-side tokens (if any), but keeping server-side tokens (if any). Normally, webAppOS will call revoke_serverless_access() from <webappos.sign_out>().