이 글의 성격은 무엇인가요?
질문 / 문제 해결
내용을 설명해주세요
앱 출시 요청을 하였더니, 로그인이 안되는 이슈가 있어서 분석하였습니다.
export const requestTossUserInfo = async (accessToken: string) => {
const options: https.RequestOptions = {
hostname: “apps-in-toss-api.toss.im”,
path: “/api-partner/v1/apps-in-toss/user/oauth2/login-me”,
method: “GET”,
headers: {
“Content-Type”: “application/json; charset=utf-8”,
Authorization: Bearer ${accessToken},
},
cert,
key,
rejectUnauthorized: false, // 서버의 인증서를 검증
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = “”;
res.on(“data”, (chunk) => (data += chunk));
res.on(“end”, () => {
const jsonResult: TossUser = JSON.parse(data).success;
resolve(jsonResult);
});
});
req.on("error", (e) => {
console.error("Request error:", e);
});
req.end();
});
};
위 코드를 통해 사용자의 정보를 얻어 왔습니다.
getUserInfo user {…,“name”:“0AX5n0Mb7APeeMP088iXL0QWWKiA3HrGuSXWCybJFPsj5aTIWg==”,…,“gender”:“0AX5n0Mb7APeeMP0WRBuhYP7Wtbxnc7lqdydvMuvr40Hcw==”,“nationality”:“0AX5n0Mb7APeeMP0UxpghYP7/e/6u6vDh78EJ+U/pu4q”,“email”:“0AX5n0Mb7APeeMP0V7Th60i9184tC8XbbbCktQ==”}
그리고 디크립션 후에 데이터를 만들어보니 아래처럼 email 필드가 비었습니다.
getUserInfo accountData {…“name”:“이단비”,“callingCode”:“”,“phone”:“”,“birthday”:“20000711”,“ci”:“”,“di”:“”,“gender”:“FEMALE”,“nationality”:“LOCAL”,“email”:“”,“updated”:“”}
정상이라면 아래처럼 아래처럼 email 값이 바뀌어 있어야 합니다. 그리고 저는 이 email값을 id로 쓰기 때문에 매우 중요합니다.
getUserInfo accountData {“id":"tothetg@naver.com”,“…“email”:“tothetg@naver.com”,“updated”:“”}
필드를 디크립션 하는 코드는 아래와 같습니다.
export function decryptUserData(
encryptedBase64: string,
): string {
if (!encryptedBase64) {
return “”
}
const IV_LENGTH = 12; // GCM nonce 길이
const TAG_LENGTH = 16; // GCM tag 길이
// 1️⃣ Base64 → Buffer 변환
const decoded = Buffer.from(encryptedBase64, 'base64');
const key = Buffer.from(process.env.TOSS_DECRYPT_KEY || "", 'base64');
// 2️⃣ 입력 길이 검증 (IV + tag 가 최소 12+16 바이트 이상이어야 함)
if (decoded.length < IV_LENGTH + TAG_LENGTH) {
throw new Error('암호문이 너무 짧습니다. IV 혹은 tag 가 누락되었습니다.');
}
// 3️⃣ IV, ciphertext, tag 분리
const iv = decoded.subarray(0, IV_LENGTH); // 12 바이트
const ciphertextWithTag = decoded.subarray(IV_LENGTH); // ciphertext + tag
const tag = ciphertextWithTag.subarray(-TAG_LENGTH); // 마지막 16 바이트
const ciphertext = ciphertextWithTag.subarray(0, -TAG_LENGTH); // tag 제외한 부분
// 4️⃣ GCM 복호화 객체 생성
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
// 5️⃣ AAD 설정 (인증에만 사용)
decipher.setAAD(Buffer.from(process.env.TOSS_AAD || "", 'utf8'));
// 6️⃣ 인증 태그 지정
decipher.setAuthTag(tag);
// 7️⃣ 실제 복호화
let decrypted = decipher.update(ciphertext);
decrypted = Buffer.concat([decrypted, decipher.final()]);
// 8️⃣ 문자열 반환
return decrypted.toString('utf8');
}
즉 토스 api를 통해 얻어온 유저정보가
디크립션 되는 경우가 있고, 안되는 경우도 있는게 현재 원인입니다.
(그런데 name,nationality,birthday는 정상적으로 디크립션 됬습니다.)
해당 테스터들의 이메일을 알 수 있을까요?
제 계정 tothetg@naver.com과 아래 계정들은 100프로 정상동작합니다.
seonjeong@toss.im
appName (선택)
myple