fix: Add authenticated image proxy for part images
Fixes 'Unauthorized' errors when loading part images in web app. Problem: - InvenTree media files require authentication - Direct image URLs return 401 Unauthorized - Browser can't send API token with image requests Solution: - Added /api/proxy/image endpoint in Flask app - Proxy fetches images with API token authentication - Returns image with correct Content-Type header - Frontend uses proxy URL instead of direct InvenTree URL Usage: - Images now load via: /api/proxy/image?url=/media/part_images/... - Proxy adds Authorization header automatically - Works for both image and thumbnail URLs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -399,6 +399,31 @@ def get_pending():
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/proxy/image')
|
||||
def proxy_image():
|
||||
"""Proxy image requests with authentication."""
|
||||
image_url = request.args.get('url')
|
||||
|
||||
if not image_url:
|
||||
return jsonify({'error': 'url parameter required'}), 400
|
||||
|
||||
# If it's a relative URL, make it absolute
|
||||
if image_url.startswith('/'):
|
||||
image_url = config['host'] + image_url
|
||||
|
||||
try:
|
||||
# Fetch image with authentication
|
||||
response = requests.get(image_url, headers={'Authorization': f"Token {config['token']}"})
|
||||
response.raise_for_status()
|
||||
|
||||
# Return image with correct content type
|
||||
content_type = response.headers.get('Content-Type', 'image/jpeg')
|
||||
return response.content, 200, {'Content-Type': content_type}
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
# WebSocket events
|
||||
@socketio.on('connect')
|
||||
def handle_connect():
|
||||
|
||||
@@ -346,12 +346,12 @@ function stockApp() {
|
||||
this.currentPart = data.part_info;
|
||||
this.currentParameters = data.parameters;
|
||||
|
||||
// Fix image URLs - convert relative paths to full InvenTree URLs
|
||||
if (this.currentPart.image && this.currentPart.image.startsWith('/')) {
|
||||
this.currentPart.image = this.config.host + this.currentPart.image;
|
||||
// Fix image URLs - use proxy for authenticated access
|
||||
if (this.currentPart.image) {
|
||||
this.currentPart.image = `/api/proxy/image?url=${encodeURIComponent(this.currentPart.image)}`;
|
||||
}
|
||||
if (this.currentPart.thumbnail && this.currentPart.thumbnail.startsWith('/')) {
|
||||
this.currentPart.thumbnail = this.config.host + this.currentPart.thumbnail;
|
||||
if (this.currentPart.thumbnail) {
|
||||
this.currentPart.thumbnail = `/api/proxy/image?url=${encodeURIComponent(this.currentPart.thumbnail)}`;
|
||||
}
|
||||
|
||||
this.log('success', `✅ Found part: ${partCode}`);
|
||||
|
||||
Reference in New Issue
Block a user