Navigation

Embed an Authenticated Chart using a Custom JWT Provider

Many websites use authentication systems that generate JWTs to represent a signed-in user. If your website produces JWTs, you can configure Charts to validate the existing tokens to authorize the rendering of embedded charts. Alternatively, if your site does not already use JWTs as a part of the authentication process, you can write code to generate JWTs explicitly for the purpose of authorizing chart renders.

This tutorial shows the latter approach. The example shows you how to generate a simple JWT for a logged in user and send it to Charts.

Charts uses the details you provided when you configure a provider to validate JWTs it receives with requests to render embedded charts. If the token is invalid or does not conform to the details you provided, Charts doesn’t render the authenticated chart view.

Prerequisites

Procedures

Enable Authenticated Embedding for a Chart

Enable authenticated embedding to generate a chart ID and Charts Base URL. You will need your chart ID and Charts Base URL to display your chart on a web page.

1

Select a dashboard.

From your dashboard page, select the dashboard containing the chart you wish to embed.

2

Select a chart.

From the dashboard, click ellipsis icon at the top-right of the chart to access its embedding information. Select Embed Chart from the dropdown menu.

3

Enable external sharing on the data source

If you have already enabled external sharing on the data source this chart uses, skip this step. If you haven’t yet enabled embedding on the data source, you can do so now. Click the Configure external sharing link.

4

Select the Authenticated tab in the dialog window.

Embed authenticated chart
5

Toggle Enable authenticated access to On.

6

(Optional) Specify a filter function to inject per user.

You can specify a function to inject a MongoDB filter document for each user who views the chart. This is useful for rendering user-specific charts.

Example

The following filter function only renders data where the ownerId field of a document matches the value of the Embedding Authentication Provider’s token’s sub field:

function getFilter(context) {
  return { ownerId: context.token.sub };
}

See also

To learn more about injecting filters per user, see Inject User-Specific Filters.

7

(Optional) Specify filterable fields for your chart.

Specify the fields on which chart viewers can filter data. By default, no fields are specified, meaning the chart cannot be filtered until you explicitly allow at least one field.

See also

To learn more about filterable fields, see Specify Filterable Fields.

8

Copy the Chart ID and Chart Base URL

Use these values in your application code together with your Embedded Authentication Provider attributes to embed your chart.

Configure Charts to use your Custom JWT Provider

1
2

From the Embedding Authentication Providers section, click Add New Provider.

3

Provide the following values to configure Charts to validate the JWT for the tutorial.

Field Value
Name Enter charts-jwt-tutorial.
Provider Select :guilabel:Custom JSON Web Token.
Signing Algorithm Select HS256.
Signing Key Enter topsecret.
4

Click Save.

Create a Web App to Display your Chart

If you already have an app in which to display your chart, you’re all set. If not, proceed with the remaining steps.

MongoDB offers a pre-built sample that shows you how to use the Embedding SDK to authenticate an embedded chart using a JWT.

Clone the GitHub repository and follow the instructions in the Readme file to begin using the app. You can customize it to use the chart you created earlier.

Customize the Node.js App

1

In your application server code, generate and return a JWT. The implementation varies based on your authentication provider.

Warning

Generate JWTs server-side to protect your signing keys from exposure.

The app.js file in the sample application uses a simple web service and the jsonwebtoken package to generate and return a JWT signed using the HS256 algorithm when a user logs in to the application with these credentials:

  • User name: admin
  • Password: password
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const jwt = require("jsonwebtoken");
const config = require("./config.js");

const app = express();
const port = 8000;

// Configuring body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());

app.post("/login", (req, res) => {
  const loginDetails = req.body;
  // mock a check against the database
  let mockedUsername = "admin";
  let mockedPassword = "password";

  if (
    loginDetails &&
    loginDetails.username === mockedUsername &&
    loginDetails.password === mockedPassword
  ) {
    let token = jwt.sign({ username: loginDetails.username }, config.secret, {
      expiresIn: "24h" // expires in 24 hours
    });
    res.json({ bearerToken: token });
  } else {
    res.status(401).send(false);
  }
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Note

Your application must handle refreshing or issuing new tokens before they expire.

In the sample application, the signing key topsecret is defined in a file in your application named config.js:

module.exports = {
  secret: "topsecret"
};
2

Embed a chart.

  1. Create a new object from the ChartsEmbedSDK class. Provide:

    • The value of the baseUrl property with the URL that points to your Charts instance. To embed one of your charts in the sample application, replace this value with the :guilabel:Base URL from your Embed Chart dialog.
    • The chartId property to specify the unique identifier of the chart you want to embed. To embed one of your charts in the sample application, replace this value with the :guilabel:Chart ID from your Embed Chart dialog.
    • The getUserToken property to specify the function that generates and returns a JWT from your authentication provider.
    • Any optional properties you want to provide. For a list of all properties you can use when you embed charts using the SDK, see SDK option reference.

    In the src/index.js file in the sample application, the login function in the getUserToken property calls the web service you created to generate a JWT. If login is successful, that function returns a valid JWT to the getUserToken property.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import ChartsEmbedSDK from "@mongodb-js/charts-embed-dom";
    import "regenerator-runtime/runtime";
    
    document
      .getElementById("loginButton")
      .addEventListener("click", async () => await tryLogin());
    
    function getUser() {
    return document.getElementById("username").value;
    }
    
    function getPass() {
    return document.getElementById("password").value;
    }
    
    async function tryLogin() {
    if (await login(getUser(), getPass())) {
      document.body.classList.toggle("logged-in", true);
      await renderChart();
    }
    }
    
    async function login(username, password) {
    const rawResponse = await fetch("http://localhost:8000/login", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ username: username, password: password })
    });
    const content = await rawResponse.json();
    
    return content.bearerToken;
    }
    
    async function renderChart() {
    const sdk = new ChartsEmbedSDK({
      baseUrl: "https://localhost/mongodb-charts-iwfxn", // ~REPLACE~ with the Base URL from your Embed Chart dialog
      chartId: "d98f67cf-374b-4823-a2a8-f86e9d480065", // ~REPLACE~ with the Chart ID from your Embed Chart dialog
      getUserToken: async function() {
        return await login(getUser(), getPass());
      }
    });
    
  2. For each chart that you want to embed, invoke the CreateChart method of the object you just created. To embed one of your charts in the sample application, replace the value of the id property with the :guilabel:Chart ID from your Embed Chart dialog.

    The following example shows an invocation of the CreateChart method in the src/index.js file in the sample application.

    const chart = sdk.createChart({ id: "d98f67cf-374b-4823-a2a8-f86e9d480065" }); // ~REPLACE~ with the Chart ID from your Embed Chart dialog
    
3

Render the chart.

Use the render method of your chart object to render it in your application.

The following example shows an invocation of the render method in the src/index.js file in the sample application.

chart.render(document.getElementById("chart"));
4

Deploy and test your application.

Charts renders the chart if it can validate the token it received with the request to render the chart. If the token isn’t valid, Charts doesn’t render the chart and displays an error code.

For more information on the Charts embedding error codes, see Embedded Chart Error Codes.