Configuring JWT for the knowledge base widget

Prev Next

If your knowledge base is private or restricted to specific users, you can use JWT (JSON Web Tokens) to securely control access to the embedded Document360 widget. This setup ensures that only authenticated users can view articles through the widget, without requiring them to sign in separately.

With JWT authentication, your system handles login and token generation. The widget then uses that token to fetch content based on each user's access level.

In this article, you'll learn:

  • How JWT authentication works for widgets

  • How to configure JWT settings in the Document360 portal

  • How to set up your backend to generate and return secure tokens

  • How to test your JWT configuration using Postman


How JWT authentication for widgets works

JWT is the recommended approach when your knowledge base visibility is set to Private or Mixed. In these cases, readers must be authenticated before the widget can display content. JWT handles this silently — readers never see a separate login screen.

Use JWT when:

  • Your knowledge base is restricted to specific users or reader groups

  • You want single sign-on access to the widget without a separate login prompt

  • You need to control which content each reader sees based on their group membership

Visual overview of the authentication process

Flowchart illustrating the login process for a knowledge base widget system.

This flow diagram shows what happens when a user loads a widget on your website. The Document360 widget communicates with your system to get a secure token before displaying content.

Sequence diagram of the authentication process

Flowchart illustrating JWT token request and validation process between components.

This sequence diagram outlines the technical flow between the user's browser, your backend, and Document360's identity server to generate and validate the JWT token.

The steps below explain the complete JWT authentication flow:

  1. User visits your website, where the Document360 widget is embedded.

  2. The widget sends a silent request to your authentication endpoint (token endpoint) configured in the widget settings.

  3. Your backend sends a request to Document360 with the required credentials (client ID, client secret) and reader details.

  4. Document360 validates the request and returns a signed JWT to your backend.

  5. Your backend sends the token back to the widget.

  6. The widget uses this token to fetch and display articles that the reader has access to.

  7. When the token expires, the widget automatically requests a new one (if configured to do so).

NOTE
The above flow happens behind the scenes. Readers never see a login screen for the widget.


Before you begin

Before configuring JWT for the widget, ensure the following:

  • You have a Project Owner or Admin role in Document360.

  • You have at least one knowledge base widget already created. If not, create one first from Connections > Knowledge base widget.

  • Your knowledge base project visibility is set to Private or Mixed. JWT is not required for public projects.

  • You have access to your backend server to implement the authentication endpoint. The code example in this article uses C#, but the same principles apply to any server-side language.

  • At least one reader group is configured in your project. The widget requires at least one valid reader group ID to render content.


Enable and configure JWT for the widget

You can implement an authentication configuration for the widget using JWT, ensuring a secure environment for private and mixed projects.

  1. Navigate to Connections () > Knowledge base widget in the left navigation bar.

    The list of widgets will appear.

  2. Hover over the desired widget you want to configure and click the Edit (✎) icon.

  3. In the Configure & connect tab, navigate to the JWT accordion and turn on the JWT Enable toggle.

Securing the Knowledge base widget

  1. Client ID: The client ID will be your project's ID.

  2. Widget ID: Since multiple widgets may exist, a Widget ID is provided for their unique purposes.

  3. Token endpoint: A token endpoint is an HTTP endpoint that allows you to obtain an access token given an authorization code.

  4. Client secret: Click Regenerate to generate the client secret. You need to save this for future purposes, and the same client secret will apply to all widgets in the future.

NOTE
The client secret is shared across all JWT-enabled widgets and chatbots in the project. If you regenerate the secret, you must update the new secret in all JWT-configured widgets and applications to prevent authentication failures.

The client secret is shown only during generation and is not stored in Document360, so save it securely.

e. Authorize URL: Paste the authorized URL from your knowledge base widget webpage.

  1. Click Save to apply changes.

Embed the authorized URL within your code and paste it into the script section on your webpage. This will implement a secure, authenticated widget that prevents unauthorized third-party access.


Implementing the auth endpoint

After configuring JWT in the portal, you'll need to set up an authentication endpoint in your backend application. This endpoint receives a request from the widget and returns a valid token in response.

The example below shows how to implement the endpoint in C#. The same logic applies to other server-side languages such as Node.js or Python — adapt the HTTP client and JSON serialization libraries as needed.

/// <summary>
/// Endpoint to authenticate a user, generate a JWT token from Document360,
/// and return it to the widget.
/// </summary>
[HttpGet]
[Route("authenticate")]
public async Task<IActionResult> WidgetAuthentication(string id)
{
    // Ensure the user is authenticated in your application
    if (!HttpContext.User.Identity.IsAuthenticated)
    {
        return Unauthorized(new { message = "User is not authenticated." });
    }

    // Define configuration values
    var clientData = new ClientDetails
    {
        ClientId = "{Client ID}",                // Replace with your project's client ID
        Secret = "{Client secret}",              // Replace with your generated client secret
        TokenEndpoint = "{Token endpoint}",      // Replace with the token endpoint URL from Document360
        WidgetId = "{Widget ID}",                // Replace with your widget ID
        SecurityGroupIds = "group1,group2",      // Replace with comma-separated reader group IDs
        TokenValidity = 900                      // Token validity in seconds (300–86400)
    };

    // Return 404 if configuration is missing
    if (clientData == null)
    {
        return NotFound(new { message = "Client configuration not found." });
    }

    // Convert the comma-separated reader group IDs into a list
    List<string> readerGroupIds = null;
    if (!string.IsNullOrEmpty(clientData.SecurityGroupIds))
    {
        readerGroupIds = clientData.SecurityGroupIds
            .Split(',')
            .Select(c => c.Trim())
            .ToList();
    }

    // Prepare the payload with user and configuration details
    var payload = new
    {
        username = "{Username}",                     // Replace with actual user data if available
        firstName = "{First name}",
        lastName = "{Last name}",
        emailId = "{Email address}",
        readerGroupIds = readerGroupIds,
        tokenValidity = clientData.TokenValidity,
        widgetId = clientData.WidgetId,
        projectId = clientData.ClientId
    };

    var payloadString = JsonConvert.SerializeObject(payload);

    try
    {
        // Send request to Document360 token endpoint
        var result = await client.RequestTokenAsync(new TokenRequest
        {
            Address = clientData.TokenEndpoint,
            ClientId = clientData.ClientId,
            ClientSecret = clientData.Secret,
            GrantType = "Widget",
            Parameters = 
            {
                { "payload", payloadString },
                { "id", clientData.ClientId }
            }
        });

        // Return the access token to the widget
        return Ok(new
        {
            accessToken = result.AccessToken,
            expiresIn = result.ExpiresIn
        });
    }
    catch (Exception ex)
    {
        // Handle unexpected errors (optional)
        return StatusCode(500, new
        {
            message = "Failed to generate token.",
            details = ex.Message
        });
    }
}
  • The tokenValidity value is set in seconds. It must be between 300 seconds (5 minutes) and 86,400 seconds (1440 minutes). If you enter a value outside this range, the system automatically adjusts it to the nearest valid value. For example, if you set tokenValidity to 60 seconds (1 minute), the system increases it to the minimum allowed value of 300 seconds (5 minutes). A value of 900 seconds (15 minutes) is a reasonable default for most use cases — shorter values improve security but increase backend load.

  • The widget requires at least one valid reader group ID to render content. Include these as a comma-separated list in the readerGroupIds parameter of the JWT payload.


Test your JWT widget configuration using Postman

After setting up JWT in the Document360 portal and implementing your backend authentication endpoint, you can use Postman to confirm that your configuration works as expected.

This test simulates what the widget does: it sends a request to your backend to fetch a valid JWT.

Set up the test in Postman

  1. Launch Postman.

  2. Select + New tab or click New > HTTP request.

  3. Set the method to POST.

  4. In the request URL field, enter the full URL of your backend endpoint.

    Example: https://yourdomain.com/authenticate

  5. Go to the Authorization tab.

  6. Under Type, select Basic Auth.

  7. Enter the following credentials:

    • Username: Your Client ID from the Document360 portal.

    • Password: Your Client Secret (generated when you created the JWT).

  8. Next, to set the request body, go to the Body tab.

  9. Select raw.

  10. Choose JSON from the dropdown on the right.

  11. Paste the following example JSON into the body:

    {
      "username": "john.doe",
      "firstName": "John",
      "lastName": "Doe",
      "emailId": "john.doe@example.com",
      "readerGroupIds": ["group1", "group2"],
      "tokenValidity": 900,
      "widgetId": "your-widget-id",
      "projectId": "your-project-id"
    }

    Replace the values with actual data from your app and Document360 configuration.

If the request is successful, you'll receive a JSON response like the following:

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 900
}
  • accessToken: This is the signed JWT that the widget will use to authorize the reader.

  • expiresIn: Token validity in seconds (15 minutes = 900 seconds).

After sending the request, check that the response status is 200 OK, indicating a successful request. The response body should contain a valid accessToken, which is the signed JWT used by the widget. Additionally, confirm that the expiresIn value matches the expected token validity duration in seconds (for example, 900 seconds for 15 minutes).

If all these values appear correctly, your JWT setup is working as intended.


Troubleshooting

If the Postman request or the live widget fails to return a valid token, refer to the common issues below.

Symptom

Likely cause

What to do

Response status is 401 Unauthorized

Incorrect Client ID or Client Secret in the request

Verify the credentials in the JWT section of the widget configuration. If you recently regenerated the secret, update it everywhere it is used.

Response status is 400 Bad Request

Malformed payload or missing required fields

Check that all required fields (username, readerGroupIds, widgetId, projectId) are present and correctly formatted.

Widget loads but displays no content

No valid reader group IDs in the token payload

Confirm that the readerGroupIds values match existing reader group IDs in your Document360 project. At least one valid group ID is required.

Token is generated but the widget shows an error

Authorize URL mismatch

Ensure the Authorize URL in the portal matches the exact URL of the webpage where the widget is embedded.

Authentication fails after regenerating the client secret

Old client secret still in use in one or more integrations

Update the new client secret in all JWT-configured widgets, chatbots, and backend applications that use it.


Next steps

After your JWT configuration is verified and working, you can:

  • Embed the widget on your website by adding the script snippet to your webpage's script section.

  • Manage reader access by updating reader group assignments in Connections > Readers.

  • Customize the widget's appearance and behavior from the Customize tab in the widget editor.