자동화 slecs

Apple OAuth 콜백 차단·세션 유실 문제 해결

목차

Apple OAuth를 처음 붙일 때 구글이나 카카오랑 같은 방식으로 접근하면 어딘가 반드시 막힌다. 직접 겪어봤다.

구글 OAuth는 콜백이 GET이다. 파라미터가 쿼리스트링에 붙어서 오니까 서버 쪽에서 받기도 쉽고, 봇 필터 같은 미들웨어도 특별히 신경 쓸 게 없다. 카카오도 마찬가지. 그런데 Apple은 response_mode=form_post를 강제한다. 콜백이 POST로 온다. Apple 서버가 사용자 브라우저를 통해 우리 서버로 form을 submit하는 구조다. 이게 문제의 시작이었다.

왜 세 군데가 동시에 터졌나

증상이 세 갈래로 나뉘었다.

버그 증상 원인
봇 차단 필터 콜백 403 Apple 서버 IP를 봇으로 인식
CORS 차단 콜백 400 Apple 콜백 URL 미허용
세션 유실 로그인 직후 튕김 콜백 후 세션 재설정 누락

하나씩 떼어서 보면 각각 별개 버그처럼 보이지만, 다 같은 원인에서 파생됐다. "Apple 콜백은 POST다"라는 전제가 빠진 채로 설계된 흐름들이었다.

BotBlockFilter가 문제가 된 건 그럴 만했다. 우리 봇 필터는 User-Agent나 IP 패턴 기반으로 자동화 트래픽을 걸러내는 로직이 들어 있었는데, Apple OAuth 콜백 요청은 Apple 서버 IP에서 날아오는 POST 요청이다. 브라우저에서 오는 일반 요청과 패턴이 다르니 필터에 걸리는 게 당연하다. 예외 처리를 안 해두면 Apple 콜백 URL(/oauth/callback/apple 같은 경로)은 항상 403이다.

CORS는 조금 다른 결이다. form_post는 cross-origin POST이기 때문에 WebMvcConfig에 Apple 도메인을 명시적으로 허용해야 한다. 구글/카카오 연동할 때는 CORS를 별로 신경 안 써도 됐던 게 습관이 돼 있다 보니 이게 빠졌다.

세션 유실은 가장 골치였다. 콜백 처리가 끝나고 리다이렉트 후에 로그인 상태가 날아가는 현상이었는데, 원인을 찾고 나니 단순했다. OAuth 콜백 컨트롤러에서 인증 완료 후 세션에 사용자 정보를 명시적으로 박아 넣는 코드가 없었다. 구글/카카오는 기존 흐름에서 처리되고 있었는데, Apple만 새로 붙이면서 그 부분이 빠진 것이다.

수정 흐름 요약

BotBlockFilter → Apple 콜백 URL 경로 패턴 예외 추가
WebMvcConfig  → CORS 허용 origin에 Apple 도메인 추가
OAuthController → 세션 재설정 로직 추가

세션 재설정 코드는 이렇게 됐다.

// Apple OAuth 콜백 처리 후 세션 명시 설정
session.setAttribute("loginUser", member);
session.setAttribute("sysId", member.getSysId());

별거 없다. 근데 이게 없으면 리다이렉트 후 세션이 날아간다.

Apple 특유의 함정 - 첫 콜백에서만 이름/이메일을 준다

이건 따로 강조할 만하다. Apple은 사용자 정보를 최초 인증 시에만 콜백 파라미터에 담아서 보내준다. 두 번째 로그인부터는 안 준다. 이름, 이메일 모두 마찬가지다.

이걸 모르고 구글처럼 매번 콜백에서 사용자 정보 갱신하는 방식으로 짜면, 첫 로그인은 되는데 나중에 보면 DB에 이름이 없거나 이메일이 비어 있는 케이스가 생긴다. 첫 콜백 때 무조건 저장해야 하고, 이미 저장된 사용자라면 그때 받은 값을 건드리지 않는 게 맞다.

// Apple은 최초 인증 시에만 name/email 제공
// member가 신규일 때만 받은 값으로 채움
if (isNewMember) {
    member.setName(appleUser.getName());
    member.setEmail(appleUser.getEmail());
}

신규 여부 체크를 빠뜨리면 기존 사용자 이름/이메일을 null로 덮어쓰는 사고가 난다.

SNS 연동은 provider별로 다 다르다

결국 구글, 카카오, Apple 세 provider를 분기 처리하게 됐다. 공통 인터페이스로 묶으려고 했지만 Apple의 form_post 방식, 최초 1회 사용자 정보 제공 제약 때문에 완전히 동일한 흐름으로 처리하기 어렵다. 어느 정도 추상화는 가능해도, Apple 전용 예외 케이스는 결국 별도 분기로 빼는 게 현실적이다.

봇 필터나 미들웨어가 있는 서비스에서 Apple OAuth를 처음 붙인다면, 403/400이 먼저 터지는 걸 감안하고 시작하는 편이 낫다. CORS, 필터 예외, 세션 재설정, 첫 콜백 사용자 정보 저장 - 이 네 가지를 체크리스트로 미리 확인하고 들어가면 삽질을 많이 줄일 수 있다.

댓글 0

첫 댓글 달아줘.