Fix: Résoudre tous les conflits d'authentification
- Nettoyer logs de debug dans auth.py - Routes /api/audio/* : auth interne au lieu de middleware global - /stream et /download : token obligatoire en query param (compat <audio>/<a>) - /waveform : auth standard via header - Polling scan/status : ajouter Authorization header - Player : token JWT sur toutes les requêtes (waveform, stream, download) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -69,7 +69,8 @@ app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
|||||||
# Protected endpoints (auth required for ALL routes)
|
# Protected endpoints (auth required for ALL routes)
|
||||||
app.include_router(tracks.router, prefix="/api/tracks", tags=["tracks"], dependencies=[Depends(require_auth)])
|
app.include_router(tracks.router, prefix="/api/tracks", tags=["tracks"], dependencies=[Depends(require_auth)])
|
||||||
app.include_router(search.router, prefix="/api/search", tags=["search"], dependencies=[Depends(require_auth)])
|
app.include_router(search.router, prefix="/api/search", tags=["search"], dependencies=[Depends(require_auth)])
|
||||||
app.include_router(audio.router, prefix="/api/audio", tags=["audio"], dependencies=[Depends(require_auth)])
|
# Audio endpoints handle auth internally (support both header and query param)
|
||||||
|
app.include_router(audio.router, prefix="/api/audio", tags=["audio"])
|
||||||
app.include_router(analyze.router, prefix="/api/analyze", tags=["analyze"], dependencies=[Depends(require_auth)])
|
app.include_router(analyze.router, prefix="/api/analyze", tags=["analyze"], dependencies=[Depends(require_auth)])
|
||||||
app.include_router(similar.router, prefix="/api", tags=["similar"], dependencies=[Depends(require_auth)])
|
app.include_router(similar.router, prefix="/api", tags=["similar"], dependencies=[Depends(require_auth)])
|
||||||
app.include_router(stats.router, prefix="/api/stats", tags=["stats"], dependencies=[Depends(require_auth)])
|
app.include_router(stats.router, prefix="/api/stats", tags=["stats"], dependencies=[Depends(require_auth)])
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""Audio streaming and download endpoints."""
|
"""Audio streaming and download endpoints."""
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Request, Query
|
from fastapi import APIRouter, Depends, HTTPException, Request, Query, status
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
@@ -9,7 +9,7 @@ from typing import Optional
|
|||||||
from ...models.database import get_db
|
from ...models.database import get_db
|
||||||
from ...models import crud
|
from ...models import crud
|
||||||
from ...core.waveform_generator import get_waveform_data
|
from ...core.waveform_generator import get_waveform_data
|
||||||
from ...core.auth import verify_token
|
from ...core.auth import verify_token, require_auth
|
||||||
from ...utils.logging import get_logger
|
from ...utils.logging import get_logger
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@@ -41,8 +41,14 @@ async def stream_audio(
|
|||||||
HTTPException: 404 if track not found or file doesn't exist
|
HTTPException: 404 if track not found or file doesn't exist
|
||||||
"""
|
"""
|
||||||
# Verify authentication via query parameter for <audio> tag
|
# Verify authentication via query parameter for <audio> tag
|
||||||
if token:
|
if not token:
|
||||||
verify_token(token)
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Authentication required",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
verify_token(token)
|
||||||
|
|
||||||
track = crud.get_track_by_id(db, track_id)
|
track = crud.get_track_by_id(db, track_id)
|
||||||
|
|
||||||
if not track:
|
if not track:
|
||||||
@@ -103,8 +109,14 @@ async def download_audio(
|
|||||||
HTTPException: 404 if track not found or file doesn't exist
|
HTTPException: 404 if track not found or file doesn't exist
|
||||||
"""
|
"""
|
||||||
# Verify authentication via query parameter for <a> tag
|
# Verify authentication via query parameter for <a> tag
|
||||||
if token:
|
if not token:
|
||||||
verify_token(token)
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Authentication required",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
verify_token(token)
|
||||||
|
|
||||||
track = crud.get_track_by_id(db, track_id)
|
track = crud.get_track_by_id(db, track_id)
|
||||||
|
|
||||||
if not track:
|
if not track:
|
||||||
@@ -141,6 +153,7 @@ async def get_waveform(
|
|||||||
track_id: UUID,
|
track_id: UUID,
|
||||||
num_peaks: int = 800,
|
num_peaks: int = 800,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
|
current_user: dict = Depends(require_auth),
|
||||||
):
|
):
|
||||||
"""Get waveform peak data for visualization.
|
"""Get waveform peak data for visualization.
|
||||||
|
|
||||||
@@ -150,6 +163,7 @@ async def get_waveform(
|
|||||||
track_id: Track UUID
|
track_id: Track UUID
|
||||||
num_peaks: Number of peaks to generate
|
num_peaks: Number of peaks to generate
|
||||||
db: Database session
|
db: Database session
|
||||||
|
current_user: Current authenticated user
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Waveform data with peaks and duration
|
Waveform data with peaks and duration
|
||||||
|
|||||||
@@ -113,8 +113,14 @@ export default function Home() {
|
|||||||
// Poll scan status
|
// Poll scan status
|
||||||
const pollInterval = setInterval(async () => {
|
const pollInterval = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
|
const token = localStorage.getItem('access_token')
|
||||||
|
const pollHeaders: HeadersInit = {}
|
||||||
|
if (token) {
|
||||||
|
pollHeaders['Authorization'] = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
|
||||||
const statusResponse = await fetch(`${getApiUrl()}/api/library/scan/status`, {
|
const statusResponse = await fetch(`${getApiUrl()}/api/library/scan/status`, {
|
||||||
headers,
|
headers: pollHeaders,
|
||||||
})
|
})
|
||||||
const status = await statusResponse.json()
|
const status = await statusResponse.json()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user