Appearance
05 오류와 점검
오류 코드별 원인과 조치, 사용자가 보는 화면, 자주 묻는 질문, stage 점검 체크리스트, 운영·문의.
| 상태 | 확정 |
| 최종 확인 | 2026-09-23 |
오류가 전달되는 위치
| 종류 | 위치 | 예 |
|---|---|---|
| 연동 서비스로 돌려보낼 수 있는 오류 | redirect_uri?error=…&error_description=…&state=…&iss=… (response_type 오류만 # fragment) | 사용자 취소, PKCE 누락 |
| 돌려보낼 수 없는 오류 | 멤버십 도메인의 한글 오류 화면 (사용자가 그대로 봄) | 미등록 client_id·redirect_uri |
| 토큰·폐기 엔드포인트 오류 | HTTP 400/401 JSON {"error": "…", "error_description": "…"} | 코드 재사용, PKCE 불일치 |
| userinfo 오류 | HTTP 400(헤더 누락) / 401 JSON | 만료·폐기 토큰 |
오류 코드
error | 위치 | 뜻 | 흔한 원인 | 조치 |
|---|---|---|---|---|
invalid_client | 토큰 401 / 인가 요청은 화면(client is invalid) | 클라이언트 인증 실패 또는 미등록 client_id | client_id 오타 · stage/prod 값 혼용 · client_secret 틀림 · 24시간 지난 옛 시크릿 | 값 확인 |
invalid_redirect_uri | 화면 | 등록되지 않은 redirect_uri | 끝 슬래시, http/https, 포트 차이 | 등록값과 문자열 완전 일치 |
invalid_request | 콜백 / 토큰 400 / userinfo 400 | 요청 형식 오류 | code_challenge 누락("Authorization Server policy requires PKCE…") · 미지원 prompt 값(create 등, "unsupported prompt value requested") · 토큰 요청 필수 본문 누락 · userinfo Authorization 누락("no access token provided") | 파라미터 확인. nonce·state 누락은 서버가 잡아주지 않는다 |
unsupported_response_type | 콜백 # | code 외 값 | response_type=token 등 | code만 |
invalid_grant | 토큰 400 | 코드·리프레시 토큰 문제 ("grant request is invalid") | 코드 60초 초과 · 코드 재사용 · code_verifier 불일치 · redirect_uri 불일치 · 리프레시 토큰 이미 교체됨 · 계정 정지·탈퇴 | 코드: 로그인부터 다시 · 리프레시: 토큰 버리고 재로그인 |
invalid_token | userinfo 401 | 액세스 토큰 만료·폐기 | 10분 경과, 폐기됨 | 새 토큰 발급 |
access_denied | 콜백 | 사용자가 취소 | 동의 화면에서 [취소] | 정상 흐름. 연동 서비스 화면으로 안내 |
login_required consent_required | 콜백 | prompt=none인데 로그인·동의가 필요("End-User authentication is required") | — | prompt=none은 화면 없는 실패를 클라이언트가 전부 처리해야 해서 권장하지 않는다. SSO는 prompt 없이도 화면 없이 통과한다 |
session_not_found | 화면 | 로그인 화면 세션 만료(30분) 또는 이미 처리된 화면 재제출 | 화면을 오래 두었거나 버튼 이중 클릭 | 처음부터 다시 시도 |
미지원 scope(profile 등)는 오류가 아니라 무시된다. 응답 scope에 빠져 있으면 요청이 무시된 것이다.
사용자가 보는 한글 화면
돌려보낼 수 없는 오류는 아래처럼 표시된다. 개발자용 코드가 함께 나오므로 사용자에게 그 코드를 받으면 원인을 바로 찾을 수 있다.
요청을 처리할 수 없습니다 사전 등록되지 않은 redirect_uri 입니다. 이용 중인 서비스의 고객센터에 아래 코드를 알려주세요.
invalid_redirect_uri
로그인 화면의 제한
연동 서비스 코드와 무관하지만 고객센터 문의 대응을 위해 알아둘 것.
| 상황 | 문구 | 풀리는 시점 |
|---|---|---|
| 비밀번호 오류 | "이메일 또는 비밀번호가 올바르지 않습니다" — 계정 존재 여부를 알려주지 않는다 | — |
| 같은 IP에서 1분 5회 실패 | "잠시 후 다시 시도해 주세요 (N초)" | 60초 |
| 같은 계정 10회 연속 실패 | "로그인 시도가 너무 많아 잠시 잠겼습니다" + 안내 메일 | 15분 |
| 정지 계정 | "이용이 정지된 계정입니다. 고객센터로 문의해 주세요" | 멤버십 운영자 해제 |
| 인증 메일 3회/15분 초과(이메일당) · 10회/15분(IP당) | "인증 메일을 너무 자주 요청했습니다" | 15분 |
자주 묻는 질문
sub가 바뀌는 경우가 있는가? — 없다. 이메일·비밀번호·로그인 수단이 바뀌어도 같다. 탈퇴 후 재가입만 새 sub다.
email이 없는 ID 토큰이 왔다. — 정상이다. 이메일 없이 가입한 이관 회원이다. sub로 회원을 만들고, 이메일이 필요하면 온보딩에서 받는다(01).
리프레시 토큰이 안 온다. — offline_access와 함께 prompt=consent를 보냈는지 확인한다. 응답 scope에 offline_access가 없으면 요청이 무시된 것이다.
두 번째 로그인에 화면이 안 뜬다. — 정상(SSO). 다시 인증시키려면 prompt=login.
같은 사용자가 웹과 앱에서 다른 sub를 받는다. — 두 클라이언트가 다른 서비스로 등록됐을 가능성. 담당자에게 확인한다. 같은 서비스면 반드시 같다.
Chrome에서만 로그인이 안 된다. — 연동 서비스 페이지의 CSP form-action이 멤버십 도메인·콜백을 막고 있는지 확인한다. 브라우저 콘솔에 CSP 위반이 찍힌다.
로컬(http://localhost)에서 개발하려면? — stage 클라이언트에 http://localhost:포트/경로를 등록한다. localhost는 http가 허용된다. stage 개방 전에는 06 로컬 실행으로 서버를 직접 띄운다(저장소 읽기 권한은 담당자에게 요청).
CI에서 로그인 흐름을 자동 테스트하고 싶다. — 로그인·동의 화면(/interaction/…)은 브라우저 전용 내부 구현이며 예고 없이 바뀔 수 있다. 그 폼을 스크립트로 제출하는 테스트에 의존하지 않는다. 자동 테스트는 인가 요청 URL 생성, 콜백 처리(state·오류), 토큰 요청·ID 토큰 검증(고정 키로 서명한 테스트 토큰)까지로 한정하고, 실제 화면 통과는 stage에서 수동 또는 실 브라우저 E2E로 확인한다.
동의 화면을 한 번도 못 봤다. — 테스트 계정이 이미 그 서비스에 연결돼 있으면 뜨지 않는다(서비스 단위). 새 계정으로 가입하거나 prompt=consent로 강제해 확인한다.
잘못된 code_verifier로 실패한 뒤 같은 코드를 다시 쓸 수 있는가? — 있다. 실패한 교환은 코드를 소모하지 않는다. 60초 안에 올바른 값으로 재시도할 수 있다.
테스트 계정을 여러 개 쓰고 싶다. — stage 로그인 화면에서 자유 가입한다. 인증 코드는 실제 메일로 발송된다.
동의 화면 문구를 바꿀 수 있는가? — 표시 이름·로고만 바뀐다. 항목·목적·기간 문구는 법적 문안이라 고정이다.
stage 점검 체크리스트
prod 클라이언트 발급 전에 통과해야 한다.
- [ ] 디스커버리 GET 200,
issuer가 설정값과 같다 - [ ] 로그인 →
sub·email수신,sub접두어가 자기 서비스 것(rm_/fm_/mb_) - [ ] 두 번째 로그인은 화면 없이 통과(SSO)
- [ ]
state불일치를 콜백에서 거부한다 - [ ] ID 토큰
aud·iss·exp·nonce·서명 검증이 실제로 실행된다(라이브러리 로그 또는 테스트) - [ ] 코드를 두 번 교환하면 두 번째가
invalid_grant - [ ] 잘못된
redirect_uri로 한글 오류 화면 - [ ] 첫 연결 사용자에게 동의 화면이 뜬다(새 계정 또는
prompt=consent로 확인) - [ ]
email없는 ID 토큰(발급 시 제공되는 이메일 없는 테스트 계정)으로 회원 생성이 된다 - [ ]
nonce·state를 항상 보내고, 콜백·ID 토큰에서 대조한다(서버가 강제하지 않는다) - [ ] 멤버십 토큰이 브라우저·앱 저장소에 남지 않는다
- [ ] (앱) 시스템 브라우저 + https 딥링크 + 백엔드 토큰 요청
- [ ] 기존 회원 전환 진입이
login_hint를 보내고(prompt=create는 지원 후 추가), 콜백이 현재 로그인 회원에 연결된다 - [ ] 실제 브라우저(Chrome·Safari·모바일)에서 로그인 → 콜백까지 이동한다
- [ ] 개인정보 처리방침에 제공받는 자 항목이 반영됐다
운영
| 항목 | 내용 |
|---|---|
| 가용성 목표 | 99.9%. 멤버십 장애 시 신규 로그인 불가, 연동 서비스 기존 세션은 유효 |
| 점검 | 사전 안내(등록된 담당자 연락처), 서비스 이용 적은 시간대 |
| 키 회전 | 서명키는 JWKS에 새 키 추가 → 전환 → 옛 키 제거 순으로 진행되어 연동 서비스 작업이 없다(kid 기반 캐시 갱신만 동작하면 됨). 클라이언트 시크릿 회전은 02 |
| 시크릿 노출 | 즉시 담당자에게 알린다. 폐기·재발급, 노출 기간의 토큰 발급 이력 확인 |
| 변경 안내 | 07 변경 이력. 연동 서비스에 영향이 있는 변경은 최소 2주 전 안내 |
문의
| 담당 | 머니박스 개발실 유원영 · yoo.wonyoung@m-box.com |
| 알려줄 것 | 환경(stage/prod), client_id, 시각, 오류 코드와 error_description, state 값(있으면) |
| 보내지 않을 것 | client_secret, 토큰, 인가 코드 |