CatPtain commited on
Commit
0dbbe1c
·
verified ·
1 Parent(s): 9abe5b6

Upload 4 files

Browse files
Files changed (4) hide show
  1. .env.example +12 -7
  2. HF_SPACES_ENV_GUIDE.md +191 -131
  3. package.json +1 -4
  4. server.js +71 -10
.env.example CHANGED
@@ -2,8 +2,7 @@
2
  # Copy these to your HF Spaces Settings → Variables
3
 
4
  # API Key Configuration
5
- API_KEYS=demo-key-123,production-key-456,client-key-789
6
- REQUIRE_API_KEY=true
7
 
8
  # Performance Settings (Optional)
9
  NODE_ENV=production
@@ -16,11 +15,17 @@ CPU_THRESHOLD=95
16
  # Instructions for Hugging Face Spaces:
17
  # 1. Go to your Space Settings
18
  # 2. Click on "Variables" tab
19
- # 3. Add each variable above (one per line, without quotes)
20
  # 4. Space will automatically restart with new configuration
21
 
22
- # Example API Keys (Generate your own secure keys):
23
- # - Use random strings of 20+ characters
24
- # - Include letters, numbers, and symbols
25
  # - Keep them secure and don't share publicly
26
- # - Consider using UUID format: 550e8400-e29b-41d4-a716-446655440000
 
 
 
 
 
 
 
2
  # Copy these to your HF Spaces Settings → Variables
3
 
4
  # API Key Configuration
5
+ API_KEY=sk-your-secure-api-key-here
 
6
 
7
  # Performance Settings (Optional)
8
  NODE_ENV=production
 
15
  # Instructions for Hugging Face Spaces:
16
  # 1. Go to your Space Settings
17
  # 2. Click on "Variables" tab
18
+ # 3. Add API_KEY variable with your secure key
19
  # 4. Space will automatically restart with new configuration
20
 
21
+ # Example API Key Generation:
22
+ # - Use random strings of 32+ characters
23
+ # - Include letters, numbers, and optionally symbols
24
  # - Keep them secure and don't share publicly
25
+ # - Consider format: sk-1234567890abcdef...
26
+ #
27
+ # Generate with Node.js:
28
+ # node -e "console.log('sk-' + require('crypto').randomBytes(32).toString('hex'))"
29
+ #
30
+ # Generate with Python:
31
+ # python -c "import secrets; print('sk-' + secrets.token_hex(32))"
HF_SPACES_ENV_GUIDE.md CHANGED
@@ -1,184 +1,244 @@
1
- # Hugging Face Spaces 环境变量设置指南
2
 
3
- ## 🔧 HF Spaces 中设置环境变量
4
 
5
- ### 方法一:通过 Web 界面设置
6
 
7
- 1. **进入 Space 设置**
8
- - 访问你的 Space:`https://huggingface.co/spaces/your-username/your-space-name`
9
- - 点击页面顶部的 **"Settings"** 标签
10
 
11
- 2. **添加环境变量**
12
- - 在设置页面中找到 **"Variables"** **"Environment Variables"** 部分
13
- - 点击 **"Add Variable"** 或 **"New Variable"**
 
14
 
15
- 3. **配置认证相关变量**
 
 
 
16
 
17
- | Variable Name | Value | Description |
18
- |---------------|-------|-------------|
19
- | `REQUIRE_API_KEY` | `true` | 启用 API 认证 |
20
- | `API_KEYS` | `key1,key2,key3` | 自定义 API 密钥列表 |
21
- | `HF_TOKEN` | `hf_your_token` | Hugging Face access token(可选) |
22
 
23
- ### 方法二:通过 Space YAML 配置
24
 
25
- 在你的 Space 根目录创建或编辑 `README.md` 文件,在顶部添加配置:
 
26
 
27
- ```yaml
28
- ---
29
- title: Page Screenshot API
30
- emoji: 📸
31
- colorFrom: blue
32
- colorTo: green
33
- sdk: docker
34
- pinned: false
35
- license: mit
36
- variables:
37
- REQUIRE_API_KEY: "true"
38
- API_KEYS: "demo-key-123,production-key-456"
39
- NODE_ENV: "production"
40
- ---
41
- ```
42
 
43
- ## 🔐 推荐的环境变量配置
44
-
45
- ### 基础配置(公开 Space)
46
  ```bash
47
- # 不设置任何环境变量,或设置:
48
- REQUIRE_API_KEY=false
 
 
49
  ```
50
 
51
- ### 受保护配置(带自定义 API Key)
52
  ```bash
53
- REQUIRE_API_KEY=true
54
- API_KEYS=your-secret-key-1,your-secret-key-2,backup-key-3
 
 
55
  ```
56
 
57
- ### 企业配置(多种认证方式)
58
- ```bash
59
- REQUIRE_API_KEY=true
60
- API_KEYS=client-key-001,client-key-002,admin-key-999
61
- NODE_ENV=production
62
- MAX_CONCURRENT_REQUESTS=5
63
- CPU_THRESHOLD=90
 
 
 
 
 
 
 
64
  ```
65
 
66
- ## 🚨 重要安全注意事项
67
 
68
- ### 安全的做法
69
- - **永远不要在代码中硬编码 token**
70
- - 使用 HF Spaces 的环境变量功能存储敏感信息
71
- - 为不同的客户端生成不同的 API key
72
- - 定期轮换 API keys
73
 
74
- ### 避免的做法
75
- - 不要在 GitHub 仓库中提交包含 token 的 `.env` 文件
76
- - 不要在 README.md 的明文部分暴露真实的 API keys
77
- - 不要使用简单易猜的 API keys
78
 
79
- ## 🔄 环境变量的工作原理
 
 
 
80
 
81
- 在你的 Space 中,这些环境变量会被自动注入到运行环境中:
 
 
 
 
 
 
82
 
83
- ```javascript
84
- // server.js 中的代码会自动读取这些环境变量
85
- const API_KEYS = process.env.API_KEYS ?
86
- process.env.API_KEYS.split(',').map(key => key.trim()) : [];
87
- const REQUIRE_API_KEY = process.env.REQUIRE_API_KEY === 'true';
88
- ```
89
 
90
- ## 📊 不同认证模式的配置示例
91
 
92
- ### 模式 1:完全开放(演示用)
93
- ```bash
94
- # 不设置任何环境变量
95
- # 所有人都可以访问 API,有基础速率限制(30次/15分钟)
 
 
 
96
  ```
97
 
98
- ### 模式 2:混合模式(推荐)
99
- ```bash
100
- REQUIRE_API_KEY=false
101
- API_KEYS=vip-key-001,premium-key-002
102
- # 未认证用户:30次/15分钟
103
- # 认证用户:100次/15分钟
104
- # HF token 用户:100次/15分钟(自动支持)
 
 
 
 
 
 
 
 
105
  ```
106
 
107
- ### 模式 3:完全保护
108
- ```bash
109
- REQUIRE_API_KEY=true
110
- API_KEYS=enterprise-key-001,client-key-002
111
- # 只有持有有效 API key 或 HF token 的用户才能访问
 
 
 
 
 
112
  ```
113
 
114
- ## 🛠️ 实际部署步骤
 
 
 
115
 
116
- ### 1. 设置环境变量
117
- 1. 进入 Space Settings → Variables
118
- 2. 添加必要的环境变量:
119
- ```
120
- REQUIRE_API_KEY: true
121
- API_KEYS: your-generated-key-1,your-generated-key-2
122
- ```
123
 
124
- ### 2. 生成安全的 API Keys
125
- ```bash
126
- # 使用 Node.js 生成随机密钥
127
- node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
128
 
129
- # 或生成 UUID 格式
130
- node -e "console.log(require('crypto').randomUUID())"
131
- ```
132
 
133
- ### 3. 验证配置
134
- 部署后访问你的 Space 的健康检查端点:
135
- ```bash
136
- curl https://your-space.hf.space/
 
 
 
 
 
 
 
 
 
137
  ```
138
 
139
- 响应应该显示认证状态:
140
  ```json
141
  {
 
 
142
  "authentication": {
 
143
  "required": true,
144
- "supportedMethods": [
145
- "X-API-Key: custom-api-key",
146
- "Authorization: Bearer custom-api-key",
147
- "Authorization: Bearer hf_token (for private Spaces)"
148
- ]
149
  }
150
  }
151
  ```
152
 
153
- ## 🔄 动态配置更新
154
 
155
- 环境变量更改后:
156
- 1. Space 会自动重启
157
- 2. 新的配置会立即生效
158
- 3. 无需重新部署代码
159
 
160
- ## 📈 监控和管理
 
 
 
 
161
 
162
- ### 检查当前配置
163
- ```bash
164
- curl https://your-space.hf.space/status
165
- ```
166
 
167
- ### 测试认证
168
- ```bash
169
- # 测试自定义 API key
170
- curl -H "X-API-Key: your-key" https://your-space.hf.space/
171
 
172
- # 测试 HF token(如果 Space 是私有的)
173
- curl -H "Authorization: Bearer hf_your_token" https://your-space.hf.space/
174
- ```
 
175
 
176
- ## 💡 最佳实践建议
177
 
178
- 1. **开发阶段**:���用开放模式进行测试
179
- 2. **生产部署**:启用认证保护
180
- 3. **密钥管理**:定期轮换 API keys
181
- 4. **访问控制**:为不同用户组分配不同的 keys
182
- 5. **监控使用**:定期检查 API 使用情况
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
- 通过以上配置,你可以完全通过 Hugging Face Spaces 的界面管理所有认证相关的环境变量,无需在代码中硬编码任何敏感信息!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Hugging Face Spaces Environment Variable Setup Guide
2
 
3
+ ## 🔐 API Key Authentication Setup
4
 
5
+ This Space supports API key authentication through environment variables. Follow these steps to enable secure access:
6
 
7
+ ### 1. Set Environment Variable in Space Settings
 
 
8
 
9
+ 1. **Go to your Space settings:**
10
+ - Navigate to your Space on Hugging Face
11
+ - Click on the "Settings" tab
12
+ - Scroll down to "Repository secrets" or "Environment variables" section
13
 
14
+ 2. **Add the API_KEY variable:**
15
+ - **Name:** `API_KEY`
16
+ - **Value:** Your secure API key (e.g., `sk-1234567890abcdef...`)
17
+ - Click "Add secret" or "Save"
18
 
19
+ 3. **Restart your Space:**
20
+ - The Space will automatically restart when you add/modify environment variables
21
+ - Wait for the Space to rebuild and restart
 
 
22
 
23
+ ### 2. Environment Variable Behavior
24
 
25
+ - **If API_KEY is set:** Authentication is required for the `/screenshot` endpoint
26
+ - **If API_KEY is not set:** Open access mode (no authentication required)
27
 
28
+ ### 3. Using the API with Authentication
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ #### Option 1: Authorization Header
 
 
31
  ```bash
32
+ curl -X POST "https://your-space.hf.space/screenshot" \
33
+ -H "Authorization: Bearer YOUR_API_KEY" \
34
+ -H "Content-Type: application/json" \
35
+ -d '{"url": "https://example.com"}'
36
  ```
37
 
38
+ #### Option 2: x-api-key Header
39
  ```bash
40
+ curl -X POST "https://your-space.hf.space/screenshot" \
41
+ -H "x-api-key: YOUR_API_KEY" \
42
+ -H "Content-Type: application/json" \
43
+ -d '{"url": "https://example.com"}'
44
  ```
45
 
46
+ #### JavaScript Example
47
+ ```javascript
48
+ const response = await fetch('/screenshot', {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Authorization': 'Bearer YOUR_API_KEY',
52
+ 'Content-Type': 'application/json'
53
+ },
54
+ body: JSON.stringify({
55
+ url: 'https://example.com',
56
+ width: 1280,
57
+ height: 720
58
+ })
59
+ });
60
  ```
61
 
62
+ ### 4. Security Best Practices
63
 
64
+ - **Generate a strong API key:** Use a cryptographically secure random string
65
+ - **Keep it secret:** Never expose the API key in client-side code or logs
66
+ - **Use HTTPS:** Always access the API over HTTPS in production
67
+ - **Rotate regularly:** Consider rotating the API key periodically
 
68
 
69
+ ### 5. Testing Authentication
 
 
 
70
 
71
+ 1. **Check authentication status:**
72
+ ```bash
73
+ curl https://your-space.hf.space/
74
+ ```
75
 
76
+ 2. **Test with correct API key:**
77
+ ```bash
78
+ curl -X POST "https://your-space.hf.space/screenshot" \
79
+ -H "Authorization: Bearer YOUR_API_KEY" \
80
+ -H "Content-Type: application/json" \
81
+ -d '{"url": "https://example.com"}'
82
+ ```
83
 
84
+ 3. **Test without API key (should fail if authentication is enabled):**
85
+ ```bash
86
+ curl -X POST "https://your-space.hf.space/screenshot" \
87
+ -H "Content-Type: application/json" \
88
+ -d '{"url": "https://example.com"}'
89
+ ```
90
 
91
+ ### 6. Error Responses
92
 
93
+ #### 401 Unauthorized (Missing or Invalid API Key)
94
+ ```json
95
+ {
96
+ "error": "Unauthorized",
97
+ "message": "Valid API key required. Please provide API key in Authorization header or x-api-key header.",
98
+ "hint": "Use \"Authorization: Bearer YOUR_API_KEY\" or \"x-api-key: YOUR_API_KEY\""
99
+ }
100
  ```
101
 
102
+ ### 7. Recommended API Key Format
103
+
104
+ Generate a secure API key using one of these methods:
105
+
106
+ #### Python
107
+ ```python
108
+ import secrets
109
+ import string
110
+
111
+ def generate_api_key(length=32):
112
+ alphabet = string.ascii_letters + string.digits
113
+ return 'sk-' + ''.join(secrets.choice(alphabet) for _ in range(length))
114
+
115
+ api_key = generate_api_key()
116
+ print(f"Generated API Key: {api_key}")
117
  ```
118
 
119
+ #### Node.js
120
+ ```javascript
121
+ const crypto = require('crypto');
122
+
123
+ function generateApiKey(length = 32) {
124
+ return 'sk-' + crypto.randomBytes(length).toString('hex').slice(0, length);
125
+ }
126
+
127
+ const apiKey = generateApiKey();
128
+ console.log(`Generated API Key: ${apiKey}`);
129
  ```
130
 
131
+ #### Online Generator
132
+ You can also use online tools like:
133
+ - `openssl rand -hex 32` (command line)
134
+ - Any secure random string generator
135
 
136
+ ### 8. Demo Page Features
 
 
 
 
 
 
137
 
138
+ The demo page automatically detects whether authentication is enabled:
 
 
 
139
 
140
+ - **With API_KEY set:** Shows API key input field
141
+ - **Without API_KEY:** Shows open access message
142
+ - **Dynamic UI:** Adapts based on authentication status
143
 
144
+ ### 9. Health Check Response Examples
145
+
146
+ #### Without API_KEY Environment Variable
147
+ ```json
148
+ {
149
+ "message": "Page Screenshot API - Hugging Face Spaces",
150
+ "version": "1.4.0",
151
+ "authentication": {
152
+ "type": "Open Access (No API Key Set)",
153
+ "required": false,
154
+ "note": "Set API_KEY environment variable to enable authentication"
155
+ }
156
+ }
157
  ```
158
 
159
+ #### With API_KEY Environment Variable
160
  ```json
161
  {
162
+ "message": "Page Screenshot API - Hugging Face Spaces",
163
+ "version": "1.4.0",
164
  "authentication": {
165
+ "type": "API Key Required",
166
  "required": true,
167
+ "note": "API key required for screenshot endpoint"
 
 
 
 
168
  }
169
  }
170
  ```
171
 
172
+ ---
173
 
174
+ ## 🚀 Quick Setup Summary
 
 
 
175
 
176
+ 1. Generate a secure API key: `sk-1234567890abcdef...`
177
+ 2. Add `API_KEY` environment variable in Space settings
178
+ 3. Set the value to your generated API key
179
+ 4. Wait for Space to restart
180
+ 5. Test with the demo page or API calls
181
 
182
+ Your Space is now secure and ready for production use! 🔐
 
 
 
183
 
184
+ ## 🔄 Environment Variable Management
 
 
 
185
 
186
+ - **Add Variable:** Space Settings → Environment Variables → Add `API_KEY`
187
+ - **Update Variable:** Modify the value and save (Space will restart)
188
+ - **Remove Variable:** Delete the variable to disable authentication
189
+ - **View Status:** Check `/` or `/status` endpoints for current auth status
190
 
191
+ ## 📱 Integration Examples
192
 
193
+ ### Frontend JavaScript
194
+ ```javascript
195
+ // Store API key securely (never in source code)
196
+ const API_KEY = localStorage.getItem('screenshot_api_key');
197
+
198
+ async function takeScreenshot(url) {
199
+ const response = await fetch('/screenshot', {
200
+ method: 'POST',
201
+ headers: {
202
+ 'Authorization': `Bearer ${API_KEY}`,
203
+ 'Content-Type': 'application/json'
204
+ },
205
+ body: JSON.stringify({ url })
206
+ });
207
+
208
+ if (response.ok) {
209
+ return await response.blob();
210
+ } else {
211
+ const error = await response.json();
212
+ throw new Error(error.message);
213
+ }
214
+ }
215
+ ```
216
 
217
+ ### Backend Integration
218
+ ```javascript
219
+ // Express.js middleware for API key validation
220
+ const SCREENSHOT_API_KEY = process.env.SCREENSHOT_API_KEY;
221
+
222
+ async function screenshotMiddleware(req, res, next) {
223
+ try {
224
+ const response = await fetch('https://your-space.hf.space/screenshot', {
225
+ method: 'POST',
226
+ headers: {
227
+ 'Authorization': `Bearer ${SCREENSHOT_API_KEY}`,
228
+ 'Content-Type': 'application/json'
229
+ },
230
+ body: JSON.stringify(req.body)
231
+ });
232
+
233
+ if (response.ok) {
234
+ const screenshot = await response.buffer();
235
+ res.set('Content-Type', 'image/jpeg');
236
+ res.send(screenshot);
237
+ } else {
238
+ res.status(response.status).json(await response.json());
239
+ }
240
+ } catch (error) {
241
+ res.status(500).json({ error: error.message });
242
+ }
243
+ }
244
+ ```
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "page-screenshot-api",
3
- "version": "1.3.0",
4
  "description": "Professional web page screenshot API service for Hugging Face Spaces",
5
  "main": "server.js",
6
  "scripts": {
@@ -24,8 +24,5 @@
24
  },
25
  "engines": {
26
  "node": ">=18.0.0"
27
- },
28
- "puppeteer": {
29
- "skipDownload": "true"
30
  }
31
  }
 
1
  {
2
  "name": "page-screenshot-api",
3
+ "version": "1.4.0",
4
  "description": "Professional web page screenshot API service for Hugging Face Spaces",
5
  "main": "server.js",
6
  "scripts": {
 
24
  },
25
  "engines": {
26
  "node": ">=18.0.0"
 
 
 
27
  }
28
  }
server.js CHANGED
@@ -6,6 +6,7 @@ const rateLimit = require('express-rate-limit');
6
 
7
  const app = express();
8
  const PORT = process.env.PORT || 7860;
 
9
 
10
  // 安全中间件
11
  app.use(helmet({
@@ -45,19 +46,41 @@ function getCpuUsage() {
45
  return Math.round((total / 1000000) % 100); // 简化的CPU使用率
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  // 健康检查
49
  app.get('/', (req, res) => {
50
  res.json({
51
  message: 'Page Screenshot API - Hugging Face Spaces',
52
- version: '1.3.0',
53
  status: 'running',
54
  platform: 'HuggingFace Spaces',
55
  authentication: {
56
- type: 'HuggingFace System Level',
57
- note: 'Authentication is handled by HuggingFace platform for private Spaces'
 
58
  },
59
  endpoints: {
60
- screenshot: 'POST /screenshot',
61
  demo: 'GET /demo',
62
  health: 'GET /',
63
  status: 'GET /status'
@@ -84,8 +107,9 @@ app.get('/status', (req, res) => {
84
  maxConcurrent: MAX_CONCURRENT
85
  },
86
  authentication: {
87
- type: 'HuggingFace System Level',
88
- note: 'No application-level authentication required'
 
89
  }
90
  });
91
  });
@@ -109,12 +133,32 @@ app.get('/demo', (req, res) => {
109
  .loading { color: #666; font-style: italic; }
110
  .error { color: #dc3545; }
111
  .success { color: #28a745; }
 
 
112
  </style>
113
  </head>
114
  <body>
115
  <h1>📸 Page Screenshot API Demo</h1>
116
  <p>Test the screenshot API with global font support</p>
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  <div class="form-group">
119
  <label>URL to screenshot:</label><br>
120
  <input type="text" id="url" value="https://www.baidu.com" placeholder="Enter website URL">
@@ -151,20 +195,36 @@ app.get('/demo', (req, res) => {
151
  const width = parseInt(document.getElementById('width').value);
152
  const height = parseInt(document.getElementById('height').value);
153
  const quality = parseInt(document.getElementById('quality').value);
 
154
 
155
  if (!url) {
156
  alert('Please enter a URL');
157
  return;
158
  }
159
 
 
 
 
 
 
 
 
160
  document.getElementById('result').innerHTML = '<p class="loading">📸 Taking screenshot...</p>';
161
 
162
  try {
 
 
 
 
 
 
 
 
 
 
163
  const response = await fetch('/screenshot', {
164
  method: 'POST',
165
- headers: {
166
- 'Content-Type': 'application/json',
167
- },
168
  body: JSON.stringify({ url, width, height, quality })
169
  });
170
 
@@ -195,7 +255,7 @@ app.get('/demo', (req, res) => {
195
  });
196
 
197
  // 截图端点
198
- app.post('/screenshot', async (req, res) => {
199
  const { url, width = 1280, height = 720, quality = 75 } = req.body;
200
 
201
  // 验证参数
@@ -306,6 +366,7 @@ app.listen(PORT, () => {
306
  console.log(`🚀 Page Screenshot API running on port ${PORT}`);
307
  console.log(`📸 Demo: http://localhost:${PORT}/demo`);
308
  console.log(`🔍 Health: http://localhost:${PORT}/`);
 
309
  });
310
 
311
  module.exports = app;
 
6
 
7
  const app = express();
8
  const PORT = process.env.PORT || 7860;
9
+ const API_KEY = process.env.API_KEY; // 从环境变量获取API密钥
10
 
11
  // 安全中间件
12
  app.use(helmet({
 
46
  return Math.round((total / 1000000) % 100); // 简化的CPU使用率
47
  }
48
 
49
+ // API鉴权中间件
50
+ function authenticate(req, res, next) {
51
+ // 如果没有设置API_KEY环境变量,跳过鉴权(开发模式)
52
+ if (!API_KEY) {
53
+ return next();
54
+ }
55
+
56
+ const authHeader = req.headers.authorization;
57
+ const apiKey = req.headers['x-api-key'] || (authHeader && authHeader.startsWith('Bearer ') ? authHeader.slice(7) : null);
58
+
59
+ if (!apiKey || apiKey !== API_KEY) {
60
+ return res.status(401).json({
61
+ error: 'Unauthorized',
62
+ message: 'Valid API key required. Please provide API key in Authorization header or x-api-key header.',
63
+ hint: 'Use "Authorization: Bearer YOUR_API_KEY" or "x-api-key: YOUR_API_KEY"'
64
+ });
65
+ }
66
+
67
+ next();
68
+ }
69
+
70
  // 健康检查
71
  app.get('/', (req, res) => {
72
  res.json({
73
  message: 'Page Screenshot API - Hugging Face Spaces',
74
+ version: '1.4.0',
75
  status: 'running',
76
  platform: 'HuggingFace Spaces',
77
  authentication: {
78
+ type: API_KEY ? 'API Key Required' : 'Open Access (No API Key Set)',
79
+ required: !!API_KEY,
80
+ note: API_KEY ? 'API key required for screenshot endpoint' : 'Set API_KEY environment variable to enable authentication'
81
  },
82
  endpoints: {
83
+ screenshot: 'POST /screenshot (requires API key if configured)',
84
  demo: 'GET /demo',
85
  health: 'GET /',
86
  status: 'GET /status'
 
107
  maxConcurrent: MAX_CONCURRENT
108
  },
109
  authentication: {
110
+ enabled: !!API_KEY,
111
+ type: API_KEY ? 'Environment Variable API Key' : 'Disabled',
112
+ note: API_KEY ? 'API key authentication is active' : 'Set API_KEY environment variable to enable authentication'
113
  }
114
  });
115
  });
 
133
  .loading { color: #666; font-style: italic; }
134
  .error { color: #dc3545; }
135
  .success { color: #28a745; }
136
+ .auth-section { background: #f8f9fa; padding: 15px; border-radius: 6px; margin-bottom: 20px; }
137
+ .auth-info { color: #6c757d; font-size: 14px; margin-top: 10px; }
138
  </style>
139
  </head>
140
  <body>
141
  <h1>📸 Page Screenshot API Demo</h1>
142
  <p>Test the screenshot API with global font support</p>
143
 
144
+ ${API_KEY ? `
145
+ <div class="auth-section">
146
+ <h3>🔐 API Authentication Required</h3>
147
+ <label>API Key:</label><br>
148
+ <input type="password" id="apiKey" placeholder="Enter your API key" style="width: 400px;">
149
+ <div class="auth-info">
150
+ ℹ️ API key is required for this Space. Contact the Space owner for access.
151
+ </div>
152
+ </div>
153
+ ` : `
154
+ <div class="auth-section">
155
+ <h3>🔓 Open Access Mode</h3>
156
+ <div class="auth-info">
157
+ ℹ️ No API key required - authentication is disabled for this Space.
158
+ </div>
159
+ </div>
160
+ `}
161
+
162
  <div class="form-group">
163
  <label>URL to screenshot:</label><br>
164
  <input type="text" id="url" value="https://www.baidu.com" placeholder="Enter website URL">
 
195
  const width = parseInt(document.getElementById('width').value);
196
  const height = parseInt(document.getElementById('height').value);
197
  const quality = parseInt(document.getElementById('quality').value);
198
+ const apiKey = document.getElementById('apiKey') ? document.getElementById('apiKey').value : '';
199
 
200
  if (!url) {
201
  alert('Please enter a URL');
202
  return;
203
  }
204
 
205
+ ${API_KEY ? `
206
+ if (!apiKey) {
207
+ alert('Please enter your API key');
208
+ return;
209
+ }
210
+ ` : ''}
211
+
212
  document.getElementById('result').innerHTML = '<p class="loading">📸 Taking screenshot...</p>';
213
 
214
  try {
215
+ const headers = {
216
+ 'Content-Type': 'application/json',
217
+ };
218
+
219
+ ${API_KEY ? `
220
+ if (apiKey) {
221
+ headers['Authorization'] = 'Bearer ' + apiKey;
222
+ }
223
+ ` : ''}
224
+
225
  const response = await fetch('/screenshot', {
226
  method: 'POST',
227
+ headers: headers,
 
 
228
  body: JSON.stringify({ url, width, height, quality })
229
  });
230
 
 
255
  });
256
 
257
  // 截图端点
258
+ app.post('/screenshot', authenticate, async (req, res) => {
259
  const { url, width = 1280, height = 720, quality = 75 } = req.body;
260
 
261
  // 验证参数
 
366
  console.log(`🚀 Page Screenshot API running on port ${PORT}`);
367
  console.log(`📸 Demo: http://localhost:${PORT}/demo`);
368
  console.log(`🔍 Health: http://localhost:${PORT}/`);
369
+ console.log(`🔐 Authentication: ${API_KEY ? 'ENABLED' : 'DISABLED'}`);
370
  });
371
 
372
  module.exports = app;