[token] ConvertAPI DWG/DXF 변환을 서버 프록시로 전환 — 토큰 클라이언트 비노출

This commit is contained in:
ysCha 2026-06-18 10:33:09 +09:00
parent 488cd54060
commit 3ccd2dc991
5 changed files with 53 additions and 15 deletions

View File

@ -10,8 +10,9 @@ SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png"
CONVERTER_API_TOKEN="mcHqQkSZP30vxCRpIWJV62ciBYT887RI"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order-dev.q-cells.jp/eos/login/autoLogin" NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order-dev.q-cells.jp/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi-dev.q-cells.jp/qm/login/autoLogin" NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi-dev.q-cells.jp/qm/login/autoLogin"

View File

@ -10,8 +10,9 @@ SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png"
CONVERTER_API_TOKEN="mcHqQkSZP30vxCRpIWJV62ciBYT887RI"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin" NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin" NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"

View File

@ -10,8 +10,9 @@ SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK" CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png"
CONVERTER_API_TOKEN="mcHqQkSZP30vxCRpIWJV62ciBYT887RI"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin" NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin" NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"

View File

@ -0,0 +1,36 @@
import { NextResponse } from 'next/server'
// ConvertAPI 토큰은 서버 전용 env 로만 보관 (NEXT_PUBLIC_ 아님) — 클라이언트 번들에 노출되지 않는다.
const CONVERTER_API_TOKEN = process.env.CONVERTER_API_TOKEN
const CONVERTER_URLS = {
dwg: process.env.CONVERTER_DWG_API_URL,
dxf: process.env.CONVERTER_DXF_API_URL,
}
export async function POST(req) {
try {
const formData = await req.formData()
const file = formData.get('file')
const type = formData.get('type')
const convertUrl = CONVERTER_URLS[type]
if (!file || !convertUrl) {
return NextResponse.json({ error: 'Invalid request' }, { status: 400 })
}
const upstream = new FormData()
upstream.append('file', file, file.name)
const res = await fetch(convertUrl, {
method: 'POST',
headers: { Authorization: `Bearer ${CONVERTER_API_TOKEN}` },
body: upstream,
})
const data = await res.json()
return NextResponse.json(data, { status: res.status })
} catch (error) {
console.error('CAD convert proxy error:', error)
return NextResponse.json({ Message: error?.message ?? 'Failed to convert CAD file' }, { status: 500 })
}
}

View File

@ -25,8 +25,6 @@ import { logger } from '@/util/logger'
* @returns {object} * @returns {object}
*/ */
export function useRefFiles() { export function useRefFiles() {
const converterDwgUrl = process.env.NEXT_PUBLIC_CONVERTER_DWG_API_URL
const converterDxfUrl = process.env.NEXT_PUBLIC_CONVERTER_DXF_API_URL
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [refImage, setRefImage] = useState(null) const [refImage, setRefImage] = useState(null)
const [refFileMethod, setRefFileMethod] = useState('1') const [refFileMethod, setRefFileMethod] = useState('1')
@ -89,9 +87,9 @@ export function useRefFiles() {
})) }))
if (file.name.split('.').pop() === 'dwg') { if (file.name.split('.').pop() === 'dwg') {
handleUploadConvertRefFile(file, converterDwgUrl); handleUploadConvertRefFile(file, 'dwg');
} else if (file.name.split('.').pop() === 'dxf') { } else if (file.name.split('.').pop() === 'dxf') {
handleUploadConvertRefFile(file, converterDxfUrl); handleUploadConvertRefFile(file, 'dxf');
} else { } else {
if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) { if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
handleUploadImageRefFile(file) handleUploadImageRefFile(file)
@ -152,7 +150,7 @@ export function useRefFiles() {
* 주소로 구글 이미지 다운로드하여 캔버스 배경으로 로드 * 주소로 구글 이미지 다운로드하여 캔버스 배경으로 로드
*/ */
const handleMapImageDown = async () => { const handleMapImageDown = async () => {
debugger; logger.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:') logger.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:')
if (queryRef.current.value === '' || queryRef.current.value === null) { if (queryRef.current.value === '' || queryRef.current.value === null) {
return return
} }
@ -250,15 +248,16 @@ export function useRefFiles() {
/** /**
* RefFile이 캐드 도면 파일일 경우 변환하여 이미지로 저장 * RefFile이 캐드 도면 파일일 경우 변환하여 이미지로 저장
* @param {*} file * @param {*} file
* @param converterUrl * @param {'dwg'|'dxf'} cadType
*/ */
const handleUploadConvertRefFile = async (file, converterUrl) => { const handleUploadConvertRefFile = async (file, cadType) => {
try { try {
const formData = new FormData() const formData = new FormData()
formData.append('file', file) formData.append('file', file)
formData.append('type', cadType)
/** 캐드 도면 파일 변환 */ /** 캐드 도면 변환은 서버 프록시 경유 — ConvertAPI 토큰을 클라이언트에 노출하지 않는다 */
const res = await post({ url: converterUrl, data: formData }) const res = await post({ url: `${Config().baseUrl}/api/image/convert`, data: formData })
logger.log('🚀 ~ handleUploadConvertRefFile ~ res:', res) logger.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
// 변환 API 가 정상 변환 대신 에러 본문(Code/Message)을 반환한 경우 그대로 throw [DXF-CONVERT-FAIL 2026-06-15] // 변환 API 가 정상 변환 대신 에러 본문(Code/Message)을 반환한 경우 그대로 throw [DXF-CONVERT-FAIL 2026-06-15]