fix(markdown): img auth via ?token= query param (Authorization header 미지원)

`<img src=>` 가 Authorization header 를 못 보내서 /api/documents/{id}/images/{key}/raw
가 401 반환 → 이미지 안 보임. 기존 /file?token= iframe 패턴과 동일하게 access token
쿼리 파라미터로 전달.

backend: get_current_user 의존성 제거하고 token 쿼리 파라미터 직접 검증 (기존 /file
엔드포인트와 동일 흐름).

frontend: MarkdownDoc 의 swap selector 가 img.src 에 ?token={getAccessToken()} 부여.
로그아웃 상태면 placeholder 유지.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-05-10 14:47:09 +09:00
parent f2a5c729b7
commit 8ca27eb573
2 changed files with 23 additions and 3 deletions
+14 -2
View File
@@ -675,14 +675,26 @@ async def get_document_file(
async def get_document_image_raw(
doc_id: int,
image_key: str,
user: Annotated[User, Depends(get_current_user)],
session: Annotated[AsyncSession, Depends(get_session)],
token: str | None = Query(None, description="Bearer token (img 태그용)"),
):
"""marker 추출 이미지 raw bytes (Phase 1B.5).
md_content 안의 `![alt](docimg:img_NNN)` ref 를 frontend selector 가 이 라우트로 변환.
인증된 사용자만 응답 (단일 사용자 환경, ownership 컬럼 없음 — get_current_user 게이트 충분).
인증된 사용자만 응답 (단일 사용자 환경, ownership 컬럼 없음).
인증: `<img src=>` 는 Authorization header 를 못 보내므로 `?token=` 쿼리 파라미터
로 access token 을 전달 — 기존 `/{doc_id}/file?token=` 엔드포인트 (iframe 용) 와
동일 패턴.
"""
from core.auth import decode_token
if not token:
raise HTTPException(status_code=401, detail="토큰이 필요합니다")
payload = decode_token(token)
if not payload or payload.get("type") != "access":
raise HTTPException(status_code=401, detail="유효하지 않은 토큰")
# 문서 존재 확인 (image_key 만 있고 doc 가 사라진 케이스 차단)
doc = await session.get(Document, doc_id)
if doc is None:
@@ -16,6 +16,7 @@
* - md_status badge (processing/success/skipped/failed) — MarkdownStatusBadge 위임
*/
import { renderDocMarkdown } from '$lib/utils/docMarkdown';
import { getAccessToken } from '$lib/api';
import MarkdownStatusBadge from '$lib/components/MarkdownStatusBadge.svelte';
type Props = {
@@ -115,8 +116,15 @@
if (!key) continue;
const alt = ph.getAttribute('data-md-image-alt') ?? '';
// <img> 는 Authorization header 를 못 보내므로 ?token= 쿼리 파라미터로 access
// token 전달 (기존 /api/documents/{id}/file?token= iframe 패턴과 동일).
const accessToken = getAccessToken();
if (!accessToken) {
// 로그아웃 상태 — placeholder 유지
continue;
}
const img = document.createElement('img');
img.src = `/api/documents/${documentId}/images/${encodeURIComponent(key)}/raw`;
img.src = `/api/documents/${documentId}/images/${encodeURIComponent(key)}/raw?token=${encodeURIComponent(accessToken)}`;
img.alt = alt;
img.loading = 'lazy';
img.className = 'md-image';