summaryrefslogtreecommitdiff
path: root/lib/users/auth
diff options
context:
space:
mode:
Diffstat (limited to 'lib/users/auth')
-rw-r--r--lib/users/auth/verifyCredentails.ts81
1 files changed, 40 insertions, 41 deletions
diff --git a/lib/users/auth/verifyCredentails.ts b/lib/users/auth/verifyCredentails.ts
index 5764db77..83a2f276 100644
--- a/lib/users/auth/verifyCredentails.ts
+++ b/lib/users/auth/verifyCredentails.ts
@@ -3,6 +3,8 @@
import bcrypt from 'bcryptjs';
import crypto from 'crypto';
+import fs from 'fs';
+import path from 'path';
import { eq, and, desc, gte, count } from 'drizzle-orm';
import db from '@/db/db';
import {
@@ -423,34 +425,33 @@ export async function completeMfaAuthentication(
}
}
-
-
-
-
// RSA 암호화 함수
function encryptPasswordWithRSA(password: string): string {
try {
- // 환경변수에서 RSA 키 가져오기
- const rsaKey = process.env.S_GIPS_RSA_KEY;
- if (!rsaKey) {
- throw new Error('RSA 키가 설정되지 않았습니다.');
+
+ // 파일에서 RSA 공개키 읽기
+ const keyPath = path.join(process.cwd(), 'lib/users/auth/public_key.pem');
+
+ // 파일 존재 여부 확인
+ if (!fs.existsSync(keyPath)) {
+ throw new Error(`RSA 키 파일을 찾을 수 없습니다: ${keyPath}`);
}
- // PEM 형태로 키 복원 (BEGIN/END 헤더 추가)
- const publicKey = `-----BEGIN PUBLIC KEY-----\n${rsaKey}\n-----END PUBLIC KEY-----`;
+ const publicKey = fs.readFileSync(keyPath, 'utf8');
// RSA 공개키로 암호화 (Java와 동일한 OAEP 패딩 사용)
- const encryptedBuffer = crypto.publicEncrypt(
- {
- key: publicKey,
- padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
- oaepHash: 'sha256',
- },
- Buffer.from(password, 'utf8')
- );
+ const encryptOptions = {
+ key: publicKey,
+ padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
+ oaepHash: 'sha256', // Java: SHA-256 (MGF1 해시도 동일 값 사용됨)
+ };
+
+ const encryptedBuffer = crypto.publicEncrypt(encryptOptions, Buffer.from(password, 'utf8'));
// Base64로 인코딩하여 반환
- return encryptedBuffer.toString('base64');
+ const base64Result = encryptedBuffer.toString('base64');
+
+ return base64Result;
} catch (error) {
console.error('RSA 암호화 오류:', error);
throw new Error('비밀번호 암호화에 실패했습니다.');
@@ -496,25 +497,14 @@ export async function verifySGipsCredentials(
// password를 RSA로 암호화
const encryptedPassword = encryptPasswordWithRSA(password);
- // URL에 query parameter 추가 (urlSearchParams 사용하는 경우 URL Safe하게 인코딩하기 때문에 fail 발생함)
- const params = {
+ // URLSearchParams를 사용하여 특수문자를 안전하게 인코딩
+ const params = new URLSearchParams({
Id: username,
Passwd: encryptedPassword,
- };
-
- const requestUrl = `${sgipsUrl}?Id=${params.Id}&Passwd=${params.Passwd}`;
-
-
- // 1. S-Gips API 호출로 인증 확인
- console.log('S-Gips API 요청:', {
- url: requestUrl,
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': `Bearer ${process.env.S_GIPS_TOKEN}`,
- },
});
+ const requestUrl = `${sgipsUrl}?${params.toString()}`;
+
const response = await fetch(requestUrl, {
method: 'GET',
headers: {
@@ -523,15 +513,24 @@ export async function verifySGipsCredentials(
},
});
- if (!response.ok) {
- if (response.status === 401) {
- return { success: false, error: 'INVALID_CREDENTIALS' };
- }
- throw new Error(`API Error: ${response.status}`);
- }
+ // 응답 본문을 한 번만 읽어서 재사용
+ const responseText = await response.text();
- const data = await response.json();
+ if (!response.ok && response.status == 401) {
+ console.error('유효하지 않은 S-GIPS JWT 응답코드 발생 :', response.status);
+ console.error('오류 응답 본문:', responseText);
+ return { success: false, error: 'INVALID_CREDENTIALS' };
+ }
+ // 텍스트를 JSON으로 파싱
+ let data;
+ try {
+ data = JSON.parse(responseText);
+ } catch (e) {
+ console.error('S-Gips Invalid JSON response:', e);
+ throw new Error('S-Gips Invalid JSON response');
+ }
+
// 2. S-Gips API 응답 확인
if (data.message === "success" && data.code === "0") {
// 3. username의 앞 8자리로 vendorCode 추출