Skip to main content

Authentication

In this step we're going to extend the server implementation so that it can authenticate itself to the APS platform, and generate access tokens for different use cases.

tip

It is a good practice to generate an "internal" token with more capabilities (for example, allowing you to create or delete files in the Data Management service) that will only be used by the server, and a "public" token with fewer capabilities that can be safely shared with the client-side logic.

Access tokens

Create an aps.js file under the services folder. This is where we will be implementing all the APS logic that will be used in different areas of our server application. Let's start by adding the following code to the file:

services/aps.js
const { AuthenticationClient, Scopes } = require('@aps_sdk/authentication');
const { OssClient, Region, PolicyKey } = require('@aps_sdk/oss');
const { ModelDerivativeClient, View, OutputType } = require('@aps_sdk/model-derivative');
const { APS_CLIENT_ID, APS_CLIENT_SECRET, APS_BUCKET } = require('../config.js');

const authenticationClient = new AuthenticationClient();
const ossClient = new OssClient();
const modelDerivativeClient = new ModelDerivativeClient();

const service = module.exports = {};

async function getInternalToken() {
const credentials = await authenticationClient.getTwoLeggedToken(APS_CLIENT_ID, APS_CLIENT_SECRET, [
Scopes.DataRead,
Scopes.DataCreate,
Scopes.DataWrite,
Scopes.BucketCreate,
Scopes.BucketRead
]);
return credentials.access_token;
}

service.getViewerToken = async () => {
return await authenticationClient.getTwoLeggedToken(APS_CLIENT_ID, APS_CLIENT_SECRET, [Scopes.ViewablesRead]);
};

The code provides two helper functions - one for generating access tokens for internal use (giving us read/write access to the Data Management buckets and objects), and one for generating tokens for public use (only giving a read access to the translation outputs from the Model Derivative service).

Server endpoints

Now we can expose this functionality through the first endpoint of our server.

Create an auth.js file under the routes subfolder with the following content:

routes/auth.js
const express = require('express');
const { getViewerToken } = require('../services/aps.js');

let router = express.Router();

router.get('/api/auth/token', async function (req, res, next) {
try {
res.json(await getViewerToken());
} catch (err) {
next(err);
}
});

module.exports = router;

Here we implement a new Express Router that will handle requests coming to our server, with the URL ending with /token, by generating a public access token and sending it back to the client as a JSON response.

Let's "mount" the router to our server application by modifying the server.js:

server.js
const express = require('express');
const { PORT } = require('./config.js');

let app = express();
app.use(express.static('wwwroot'));
app.use(require('./routes/auth.js'));
app.listen(PORT, function () { console.log(`Server listening on port ${PORT}...`); });

Try it out

Let's see if our new server endpoint works.

If the application is still running, restart it (for example, using Run > Restart Debugging, or by clicking the green restart icon), otherwise start it again (using Run > Start Debugging, or by pressing F5). When you navigate to http://localhost:8080/api/auth/token in the browser, the server should now respond with a JSON object containing the access token data.

tip

If you are using Google Chrome, consider installing JSON Formatter or a similar extension to automatically format JSON responses.

Server Response