Files
weeklyreport/server/api/auth/synology/verify.post.ts
Hyoseong Jo ee736fb7cc fix: Synology SSO createSession 호출 수정
- insertReturning으로 history_id 반환받기
- createSession에 4개 파라미터 전달 (employeeId, historyId, ip, userAgent)
- setSessionCookie로 세션 쿠키 설정
2026-01-11 23:52:27 +09:00

123 lines
3.6 KiB
TypeScript

/**
* Synology SSO Access Token 검증 및 로그인 처리
* POST /api/auth/synology/verify
*/
import { queryOne, execute, insertReturning } from '~/server/utils/db'
import { createSession, setSessionCookie } from '~/server/utils/session'
import { getClientIp } from '~/server/utils/ip'
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const { accessToken } = body
const ip = getClientIp(event)
if (!accessToken) {
throw createError({
statusCode: 400,
message: 'Access token이 없습니다.'
})
}
const config = useRuntimeConfig()
console.log('[Synology SSO] Access Token:', accessToken)
try {
// SSOAccessToken.cgi로 사용자 정보 조회
const tokenInfoUrl = `${config.synologyServerUrl}/webman/sso/SSOAccessToken.cgi?action=exchange&access_token=${accessToken}&app_id=${config.synologyClientId}`
console.log('[Synology SSO] Requesting:', tokenInfoUrl)
let tokenResponse = await $fetch<any>(tokenInfoUrl)
// 문자열로 온 경우 JSON 파싱
if (typeof tokenResponse === 'string') {
tokenResponse = JSON.parse(tokenResponse)
}
console.log('[Synology SSO] Response:', JSON.stringify(tokenResponse, null, 2))
if (!tokenResponse.success) {
throw createError({
statusCode: 401,
message: 'Synology 토큰 검증에 실패했습니다.'
})
}
const synologyUsername = tokenResponse.data?.user_name
if (!synologyUsername) {
throw createError({
statusCode: 401,
message: 'Synology 사용자명을 가져올 수 없습니다.'
})
}
console.log('[Synology SSO] Username:', synologyUsername)
// username@osolit.net 으로 매칭
const synologyEmail = `${synologyUsername}@osolit.net`
const employee = await queryOne<any>(`
SELECT employee_id, employee_name, is_active, password_hash,
synology_id, synology_email, employee_email
FROM wr_employee_info
WHERE synology_id = $1
OR employee_email = $2
`, [synologyUsername, synologyEmail])
if (!employee) {
throw createError({
statusCode: 404,
message: `Synology 계정 "${synologyUsername}"과 연결된 사용자를 찾을 수 없습니다. (${synologyEmail}) 관리자에게 문의하세요.`
})
}
if (!employee.is_active) {
throw createError({
statusCode: 403,
message: '비활성화된 계정입니다.'
})
}
// Synology ID 업데이트
await execute(`
UPDATE wr_employee_info
SET synology_id = $1, synology_linked_at = NOW()
WHERE employee_id = $2
`, [synologyUsername, employee.employee_id])
// 로그인 이력 기록
const loginHistory = await insertReturning(`
INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_email)
VALUES ($1, 'SYNOLOGY', $2, NOW(), $3)
RETURNING history_id
`, [employee.employee_id, ip, synologyEmail])
// 세션 생성
const userAgent = getHeader(event, 'user-agent') || null
const sessionId = await createSession(
employee.employee_id,
loginHistory.history_id,
ip,
userAgent
)
setSessionCookie(event, sessionId)
return {
success: true,
needPasswordSet: !employee.password_hash
}
} catch (error: any) {
console.error('[Synology SSO] Error:', error)
if (error.statusCode) {
throw error
}
throw createError({
statusCode: 500,
message: 'Synology 로그인 처리 중 오류가 발생했습니다.'
})
}
})