Documentation Index

Fetch the complete documentation index at: https://docs.document360.com/llms.txt

Use this file to discover all available pages before exploring further.

Descargo de responsabilidad: Este artículo se generó mediante traducción automática.

Implementa JWT en tu aplicación

Prev Next

Tras completar la configuración de JWT en Document360, tu aplicación necesita una ruta backend para gestionar el paso final del flujo de inicio de sesión.

Esta ruta:

  • Valida que el usuario ya está autenticado en tu aplicación
  • Envía una solicitud segura a la URL de generación de código de Document360
  • Recupera un código de autorización de un solo uso
  • Redirige al usuario al sitio de la base de conocimientos con ese código

NOTA

Los lectores no necesitan una cuenta Document360 separada. La autenticación se gestiona íntegramente a través de tu aplicación. Una cuenta en tu aplicación es suficiente para que un lector acceda a la base de conocimiento.


Ejemplos de código

Los ejemplos siguientes muestran cómo implementar la ruta de autenticación backend en C#, Node.js y Java.

C#

/// <summary>
/// Example endpoint to authenticate a user and retrieve a token from the identity server,
/// and redirect the user to the Knowledge Base (KB) using the token code.
/// </summary>
/// <param name="clientId">Client ID issued for your application</param>
/// <param name="clientSecret">Client secret associated with the client ID</param>
/// <returns>Redirects to the KB with the issued code</returns>
[HttpGet]
[Route("authenticate")]
public async Task<IActionResult> AuthenticateAsync(string clientId, string clientSecret)
{
    if (!HttpContext.User.Identity.IsAuthenticated)
    {
        // user is not authenticated, redirect to an error or login page
        return Unauthorized(new { message = "User not authenticated" });
    }

    // Ensure you have the correct client ID and secret from your Document360 JWT configuration
    var authToken = Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}");

    // Create an HttpClient instance
    using var httpClient = new HttpClient();

    // Set the Authorization header with Basic authentication
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));

    // Prepare the payload with user information
    var payload = new
    {
        username = User.Identity.Name,
        firstName = "FirstName", // Replace or customize as needed
        lastName = "LastName",
        emailId = "user@example.com", // Replace with actual user email
        readerGroupIds = new List<string> { "group1", "group2" }, // Replace with actual reader group IDs if needed (Optional)
        tokenValidity = 3600 // Token validity in seconds (Optional, default is 5 minutes)
    };

    var payloadContent = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");

    // Identity server token endpoint - replace with your actual URL
    string identityServerUrl = "codeGeneration endpoint, you can find that in JWT config portal";
    // KB login URL to redirect after successful token issuance
    string kbLoginUrl = "https://{your subdomain}.document360.io";

    var response = await httpClient.PostAsync(identityServerUrl, payloadContent);

    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();
        var tokenJson = JObject.Parse(content);
        // Extract the code from the response
        var tokenCode = (string)tokenJson.SelectToken("code");

        // Construct the KB login URL with code query parameter
        string finalRedirectUrl = $"{kbLoginUrl}?code={tokenCode}";

        return Redirect(finalRedirectUrl);
    }
    else
    {
        // Handle error response from the identity server
        var error = await response.Content.ReadAsStringAsync();
        return StatusCode((int)response.StatusCode, new { error = "Token request failed", details = error });
    }
}

Node.js

const express = require('express');
const https = require('https');
const axios = require('axios');
const app = express();

app.use(express.json());

const clientId = 'your-client-id';
const clientSecret = 'your-client-secret';
const codeGenerationUrl = 'https://identity.document360.net/jwt/generateCode';
const kbLoginUrl = 'https://your-subdomain.document360.net/jwt/authorize';

app.get('/authenticate', async (req, res) => {
  try {
    const isAuthenticated = true; // Replace with your actual auth logic

    if (!isAuthenticated) {
      return res.status(401).json({ message: 'User not authenticated' });
    }

    const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

    const payload = {
      username: 'john.doe',
      firstName: 'John',
      lastName: 'Doe',
      emailId: 'john.doe@example.com',
      readerGroupIds: ['group1', 'group2'],
      tokenValidity: 3600
    };

    const response = await axios.post(
      codeGenerationUrl,
      payload,
      {
        headers: {
          'Authorization': `Basic ${authHeader}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        httpsAgent: new https.Agent({ maxVersion: 'TLSv1.2' })
      }
    );

    const tokenCode = response.data?.code;

    if (!tokenCode) {
      return res.status(500).json({ message: 'No code received from Document360' });
    }

    console.log("Redirecting to:", `${kbLoginUrl}?code=${tokenCode}`);
    return res.redirect(`${kbLoginUrl}?code=${tokenCode}`);

  } catch (error) {
    return res.status(500).json({
      message: 'JWT SSO failed',
      details: error.response?.data || error.message
    });
  }
});

Java

import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.nio.charset.StandardCharsets;
import java.util.*;

@RestController
public class JwtSsoController {

    private final String clientId = "your-client-id";
    private final String clientSecret = "your-client-secret";
    private final String codeGenerationUrl = "https://identity.document360.io/api/jwt/generate-code";
    private final String kbLoginUrl = "https://your-subdomain.document360.io/jwt/authorize";

    @GetMapping("/authenticate")
    public ResponseEntity<?> authenticate() {
        // Example: Check if user is authenticated in your system
        boolean isAuthenticated = true; // Replace with actual logic
        if (!isAuthenticated) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("User not authenticated");
        }

        // Create Basic Auth header
        String auth = clientId + ":" + clientSecret;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Basic " + encodedAuth);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        // Construct payload
        Map<String, Object> payload = new HashMap<>();
        payload.put("username", "john.doe");
        payload.put("firstName", "John");
        payload.put("lastName", "Doe");
        payload.put("emailId", "john.doe@example.com");
        payload.put("readerGroupIds", Arrays.asList("group1", "group2"));
        payload.put("tokenValidity", 3600);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(payload, headers);
        RestTemplate restTemplate = new RestTemplate();

        try {
            ResponseEntity<Map> response = restTemplate.postForEntity(codeGenerationUrl, request, Map.class);

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                String tokenCode = (String) response.getBody().get("code");

                if (tokenCode == null || tokenCode.isEmpty()) {
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .body("No code returned from Document360");
                }

                // Redirect to the KB site with code
                String redirectUrl = UriComponentsBuilder.fromHttpUrl(kbLoginUrl)
                        .queryParam("code", tokenCode)
                        .toUriString();

                HttpHeaders redirectHeaders = new HttpHeaders();
                redirectHeaders.setLocation(java.net.URI.create(redirectUrl));
                return new ResponseEntity<>(redirectHeaders, HttpStatus.FOUND);

            } else {
                return ResponseEntity.status(HttpStatus.BAD_GATEWAY)
                        .body("Failed to get code from Document360: " + response.getStatusCode());
            }

        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("JWT SSO error: " + ex.getMessage());
        }
    }
}

Lista de comprobación para desarrolladores

Antes de lanzarse, verifica lo siguiente:

  • Registra la URL de Inicio de Sesión, la URL de Llamada y la URL de generación de código en la configuración de tu JWT.
  • Guarda el secreto del cliente de forma segura. Solo se muestra una vez en el momento de su creación.
  • Implementa lógica backend para llamar a la URL de generación de código usando HTTP Basic Auth.
  • Firma el JWT en tu backend usando tu secreto de cliente. Nunca expongas la lógica de signos en el lado del cliente.
  • Aplica HTTPS en todos los endpoints implicados en el flujo de autenticación.
  • Prueba el comportamiento de la sesión, la expiración del token y la renovación automática de la sesión antes de lanzarse.
  • Monitoriza los registros del backend en busca de errores 401, que normalmente indican códigos de autorización caducados o discrepancias de tokens.

Redirigir a una página específica después de iniciar sesión

Por defecto, tras iniciar sesión, los lectores son redirigidos a la página principal de tu base de conocimiento.

  • Si tu página principal no está publicada, los lectores son redirigidos a la /docs página.
  • Para redirigir a los lectores a una página diferente de tu base de conocimiento, configura la redirección usando el siguiente patrón de URL.

Patrón de URL

https://<Knowledge base URL>/jwt/authorize?code=<code>&redirectUrl=<redirect path>

Parámetros

  • <Knowledge base URL>: la URL principal de tu sitio de base de conocimiento.
  • <code>: el código generado por el endpoint de generación de código Document360.
  • <redirect path>: la URL a la que quieres que los lectores lleguen tras iniciar sesión.

Ejemplo

https://example.document360.io/jwt/authorize?code=FOTaS_SW6dLGytQXvrG_rRFGhyPvrDDrgxJAZzYvJcY&redirectUrl=/docs/5-basic-things-to-get-started

NOTA

Document360 enviará la URL de Redirección al redirectPath punto final de inicio de sesión. Cuando el punto final de inicio de sesión redirige de nuevo a la base de conocimientos con el código de autenticación, debería devolver la URL de Redirección como redirectUrl parámetro.

En KB Site 2.0, la redirección se gestiona mediante cookies en lugar del redirectUrl parámetro. Si tu implementación en JWT se basa en la redirección de cadenas de consulta usando el redirectUrl parámetro, el enfoque basado en cookies no soporta este parámetro. Puede que necesites actualizar tu implementación o contactar con el soporte para aclarar más.