[token] ConvertAPI DWG/DXF 변환을 서버 프록시로 전환 — 토큰 클라이언트 비노출 #924
@ -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_yAS4QDalL9jgQ7vS"
|
||||
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
|
||||
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_MUSUBI_AUTO_LOGIN_URL="https://q-musubi-dev.q-cells.jp/qm/login/autoLogin"
|
||||
|
||||
@ -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_yAS4QDalL9jgQ7vS"
|
||||
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
|
||||
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_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
|
||||
|
||||
@ -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_yAS4QDalL9jgQ7vS"
|
||||
NEXT_PUBLIC_CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
NEXT_PUBLIC_CONVERTER_DXF_API_URL="https://v2.convertapi.com/convert/dxf/to/png?Secret=secret_a0FLEK6M2oTpXInK"
|
||||
CONVERTER_DWG_API_URL="https://v2.convertapi.com/convert/dwg/to/png"
|
||||
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_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"
|
||||
|
||||
36
src/app/api/image/convert/route.js
Normal file
36
src/app/api/image/convert/route.js
Normal 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 })
|
||||
}
|
||||
}
|
||||
@ -25,8 +25,6 @@ import { logger } from '@/util/logger'
|
||||
* @returns {object}
|
||||
*/
|
||||
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 [refImage, setRefImage] = useState(null)
|
||||
const [refFileMethod, setRefFileMethod] = useState('1')
|
||||
@ -89,9 +87,9 @@ export function useRefFiles() {
|
||||
}))
|
||||
|
||||
if (file.name.split('.').pop() === 'dwg') {
|
||||
handleUploadConvertRefFile(file, converterDwgUrl);
|
||||
handleUploadConvertRefFile(file, 'dwg');
|
||||
} else if (file.name.split('.').pop() === 'dxf') {
|
||||
handleUploadConvertRefFile(file, converterDxfUrl);
|
||||
handleUploadConvertRefFile(file, 'dxf');
|
||||
} else {
|
||||
if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
|
||||
handleUploadImageRefFile(file)
|
||||
@ -152,7 +150,7 @@ export function useRefFiles() {
|
||||
* 주소로 구글 맵 이미지 다운로드하여 캔버스 배경으로 로드
|
||||
*/
|
||||
const handleMapImageDown = async () => {
|
||||
debugger; logger.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:')
|
||||
logger.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:')
|
||||
if (queryRef.current.value === '' || queryRef.current.value === null) {
|
||||
return
|
||||
}
|
||||
@ -250,15 +248,16 @@ export function useRefFiles() {
|
||||
/**
|
||||
* RefFile이 캐드 도면 파일일 경우 변환하여 이미지로 저장
|
||||
* @param {*} file
|
||||
* @param converterUrl
|
||||
* @param {'dwg'|'dxf'} cadType
|
||||
*/
|
||||
const handleUploadConvertRefFile = async (file, converterUrl) => {
|
||||
const handleUploadConvertRefFile = async (file, cadType) => {
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('type', cadType)
|
||||
|
||||
/** 캐드 도면 파일 변환 */
|
||||
const res = await post({ url: converterUrl, data: formData })
|
||||
/** 캐드 도면 변환은 서버 프록시 경유 — ConvertAPI 토큰을 클라이언트에 노출하지 않는다 */
|
||||
const res = await post({ url: `${Config().baseUrl}/api/image/convert`, data: formData })
|
||||
logger.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
|
||||
|
||||
// 변환 API 가 정상 변환 대신 에러 본문(Code/Message)을 반환한 경우 그대로 throw [DXF-CONVERT-FAIL 2026-06-15]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user