yx_only_office_flutter/JWT_FIX_GUIDE.md

181 lines
4.4 KiB
Markdown

# 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](https://api.onlyoffice.com/docs/docs-api/additional-api/signature/), 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.
```yaml
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:**
```dart
// 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`**
```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`:
```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
```dart
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:
```dart
{
'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
- [ONLYOFFICE Signature Documentation](https://api.onlyoffice.com/docs/docs-api/additional-api/signature/)
- [JWT.io - Introduction to JSON Web Tokens](https://jwt.io/introduction)
## Testing
All tests pass successfully:
```bash
flutter test test/onlyoffice_viewer_unit_test.dart
# ✅ All 20 tests passed!
```