Next.js 13 에서의 redirect 오류를 해결한 과정을 적어둔다.
Next.js 13 으로 개발되어 운영 중인 서비스에 Apple ID를 이용한 로그인 기능이 있었다. 이게 언제부터인지(혹은 애초에 제대로 작동한 적이 없었던 것인지..) 로그인이 되지 않는 걸 발견했는데, 당연히 고쳐야 했다. 오래 전에 다른 사람이 개발한 기능이었고 히스토리도 남아있는 문서도 없어서 열심히 코드를 뜯어봤다.
애플 로그인을 한 뒤에 서비스로 돌아오지 않는다. 서비스로 돌아오지 않으면 애플 서버가 발급한 code
와 id_token
을 알 수 없기 때문에 사용자가 인증됐는지 서비스에서 확인할 수 없고 로그인이 불가하다.
구현할 때 애플 로그인 서버에서의 인증 절차가 끝나면 애플이 발급한 code
와 id_token
값을 갖고 서비스로 돌아오도록 redirect uri
를 입력해줬는데, 여기서 무한 pending 상태가 지속되며 해당 redirect uri
에서 약 30초 정도 지난 후에는 타임아웃으로 로그인 프로세스가 중단됐다.
일단 react-apple-login
패키지를 사용하기 때문에, 서비스에서 직접적으로 애플 로그인 페이지를 호출하는 부분은 없었고, 입력한 Apple ID와 비밀번호, 그리고 정보 제공 동의까지 잘 넘어갔으므로 애플에 인증을 요청하는 부분은 문제가 없어 보였다.
인증 후의 과정이 문제였는데, redirect uri
가 가리키는 서비스 내의 페이지(/callback/apple
이라고 하자)로 이동 후에 redirect 과정이 한 차례 더 있었다.
정리하면 다음과 같은 흐름이다.
- 애플 로그인 페이지에서 로그인 완료
- 애플 서버에서
/callback/apple
로 유저 인증 정보 전송/callback/apple
에서 애플 유저 정보(이메일, 이름)을/callback
으로 전송/callback
에서 각 플랫폼(카카오, 네이버, 애플..)에서 받은 유저 정보를 공통된 형식에 맞춰서user_info
로 가공user_info
를/social
로 전송해서 폼에 띄워주고 추가 정보 입력 유도
/callback
이 각 소셜 로그인 데이터가 모이는 미들웨어 역할을 하는 것처럼 보였는데, pending 현상은 3번에서 일어났다.
/callback/apple
에서 /callback
으로 redirect 를 수행할 때, 다음과 같이 바꿔줬다.
기존 코드
import {redirect} from 'next/navigation'
...
redirect('/callback')
...
수정 코드
import {NextResponse} from 'next/server'
...
NextResponse.redirect(new URL('/callback'), 303)
...