yx_only_office_flutter/JWT_FIX_GUIDE.md

4.4 KiB

JWT Authentication Fix for OnlyOffice Docs 7.1+

Problem

The error you encountered:

[ERROR] nodeJS - auth missing required parameter document.key (since 7.1 version)

And the Chinese error dialog: "错误 - 文档安全令牌的格式不正确" (Document security token format is incorrect)

Root Cause

Starting with OnlyOffice Docs version 7.1, when JWT authentication is enabled on the server, the entire configuration object must be signed with a JWT token. Simply passing a pre-generated JWT token as a separate field is not sufficient.

According to the ONLYOFFICE signature documentation, the token must:

  1. Be generated using the JWT secret key configured on the server
  2. Include the entire configuration object (including document.key and all other parameters)
  3. Use the HS256 algorithm

Changes Made

1. Added JWT Package

File: pubspec.yaml

Added dart_jsonwebtoken: ^2.14.1 to properly sign JWT tokens.

dependencies:
  flutter:
    sdk: flutter
  crypto: ^3.0.7
  webview_flutter: ^4.13.0
  webview_flutter_android: ^4.10.10
  webview_flutter_wkwebview: ^3.0.0
  dart_jsonwebtoken: ^2.14.1  # NEW

2. Updated OnlyOfficeViewer Widget

File: lib/onlyoffice_viewer.dart

Changed parameter name:

  • Old: final String? token;
  • New: final String? jwtSecret;

Updated JWT signing logic:

// Sign the entire config with JWT if secret is provided
if (widget.jwtSecret != null && widget.jwtSecret!.isNotEmpty) {
  final jwt = JWT(config);
  final token = jwt.sign(SecretKey(widget.jwtSecret!), algorithm: JWTAlgorithm.HS256);
  config['token'] = token;
}

The key difference: Instead of just adding a pre-made token to the config, we now:

  1. Create a JWT from the entire config object
  2. Sign it with the secret key using HS256 algorithm
  3. Add the resulting signed token to the config

3. Updated Example App

File: example/lib/main.dart

// Old:
static const String jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';

// New:
static const String jwtSecret = '6Yr6DGoVV3ACS6GtVgdH453mXxLftd6Q';

// Usage:
OnlyOfficeViewer(
  onlyOfficeServerUrl: onlyOfficeServerUrl,
  fileUrl: currentDoc.url,
  jwtSecret: jwtSecret,  // Pass the secret, not a pre-made token
)

4. Updated Tests

File: test/onlyoffice_viewer_unit_test.dart

  • Updated all test cases to use jwtSecret instead of token
  • Added new test to verify JWT token generation and validation
  • Updated TestHelper to match the real implementation

How to Use

For Your Server Configuration

You need to provide the JWT secret that matches your OnlyOffice server configuration. This secret is configured in your OnlyOffice server's local.json:

{
  "services": {
    "CoAuthoring": {
      "secret": {
        "inbox": {
          "string": "YOUR_SECRET_HERE"
        },
        "outbox": {
          "string": "YOUR_SECRET_HERE"
        }
      },
      "token": {
        "enable": {
          "browser": true,
          "request": {
            "inbox": true,
            "outbox": true
          }
        }
      }
    }
  }
}

Example Usage

OnlyOfficeViewer(
  onlyOfficeServerUrl: 'https://document.23544.com/',
  fileUrl: 'https://example.com/document.pptx',
  jwtSecret: '6Yr6DGoVV3ACS6GtVgdH453mXxLftd6Q', // Your server's JWT secret
)

What Gets Signed

The JWT token now contains the entire configuration object:

{
  'document': {
    'fileType': 'pptx',
    'key': 'sha256_hash_of_url',
    'title': 'document.pptx',
    'url': 'https://example.com/document.pptx',
  },
  'documentType': 'slide',
  'editorConfig': {
    'mode': 'view',
    'lang': 'zh-CN'
  },
  'type': 'mobile',
}

This entire object is signed with HS256 algorithm using your secret, and the resulting JWT is added as the token field.

Security Note

⚠️ Never commit your JWT secret to version control!

Store it securely:

  • Use environment variables
  • Use secure configuration management
  • Use encrypted secret storage

References

Testing

All tests pass successfully:

flutter test test/onlyoffice_viewer_unit_test.dart
# ✅ All 20 tests passed!