You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Web应用中如何将服务端start.js的token传递至客户端viewer.js?

Solution for Sharing Forge Token Between Express Backend and Viewer Frontend

Hey there! Let's work through getting that Forge token from your Node.js backend to your client-side Viewer. The core issue here is that your server-side token lives in the Node.js runtime—completely separate from the browser's environment—so global variables or direct method calls can't bridge that gap. The reliable fix is to create a dedicated API endpoint on your server that the client can call to fetch the token, then initialize the Viewer once you have it.

Let's break down the corrected code and steps:

Step 1: Fix & Enhance the Backend (start.js)

First, we'll properly set up the Forge OAuth client, handle token refresh, and add an API route to serve the token:

const ForgeSDK = require('forge-apis');
const express = require('express');
const path = require('path');

// Replace these with your actual Forge credentials
const FORGE_CLIENT_ID = 'YOUR_CLIENT_ID';
const FORGE_CLIENT_SECRET = 'YOUR_CLIENT_SECRET';

var app = express();
app.use('/static', express.static(__dirname + '/static'));

// Initialize Forge OAuth 2.0 client with required scopes
const oAuth2TwoLegged = new ForgeSDK.OAuth2TwoLegged(
  FORGE_CLIENT_ID,
  FORGE_CLIENT_SECRET,
  ['data:read', 'viewables:read'], // Scopes needed for Viewer access
  true
);

let token; // Properly declare token variable to avoid global pollution

/**
 * Handle token generation and automatic refresh
 */
async function refreshToken() {
  try {
    const credentials = await oAuth2TwoLegged.authenticate();
    token = credentials.access_token;
    console.log('New valid token generated:', token);
    // Refresh token 60 seconds before it expires (Forge tokens last 1 hour)
    setTimeout(refreshToken, (credentials.expires_in - 60) * 1000);
  } catch (err) {
    console.error('Failed to refresh token:', err);
  }
}

// Generate initial token when the app starts
refreshToken();

// Add API endpoint to return the current valid token
app.get('/api/token', (req, res) => {
  if (token) {
    res.json({ access_token: token });
  } else {
    res.status(500).json({ error: 'Token not yet generated' });
  }
});

app.get('/', function(req, res) {
  res.sendFile(path.join(__dirname + '/index.html'));
});

app.listen(3000, function () {
  console.log('Token provider listening on port 3000');
});

Key improvements here:

  • Properly initialized the Forge OAuth client with your credentials and Viewer-required scopes
  • Added automatic token refresh to avoid serving expired tokens
  • Created a /api/token endpoint that returns the valid token as JSON for the client

Step 2: Update the Client-Side (viewer.js)

Now modify your client script to fetch the token from the new endpoint before initializing the Viewer:

async function initViewer() {
  try {
    // Fetch the token from your backend API
    const response = await fetch('/api/token');
    if (!response.ok) {
      throw new Error('Failed to retrieve token from server');
    }
    const { access_token } = await response.json();

    // Initialize the Viewer with the fetched token
    const viewerOptions = {
      env: 'AutodeskProduction',
      accessToken: access_token
    };

    Autodesk.Viewing.Initializer(viewerOptions, () => {
      // Your Viewer setup logic goes here
      // Example:
      const viewerContainer = document.getElementById('viewer');
      const viewer = new Autodesk.Viewing.GuiViewer3D(viewerContainer);
      viewer.start();
      // Load your model document...
    });
  } catch (err) {
    console.error('Error initializing Viewer:', err);
  }
}

// Trigger initialization when the page finishes loading
document.addEventListener('DOMContentLoaded', initViewer);

Why Your Previous Attempts Didn't Work

  • Global variables: The token in your server-side start.js exists in the Node.js process, not the browser's window object—they’re separate environments with no shared memory.
  • Global methods: Server-side functions can’t be called directly from the browser unless exposed via an API endpoint.
  • HTTP requests: You likely either didn’t set up the correct endpoint, or tried initializing the Viewer before the token request finished (not handling the asynchronous nature of fetch calls).

Important Notes

  • Token Expiry: The backend automatically refreshes the token before it expires, so the client always gets a valid token when calling /api/token.
  • Security: Since this uses a two-legged token, ensure your server is only accessible to trusted users, or add user authentication if your use case requires it.

内容的提问来源于stack exchange,提问作者gchap

火山引擎 最新活动