본문 바로가기
카테고리 없음

Next js / Nice Api 사파리 아이폰 405 에러 트러블 슈팅 과정

by Integer Essence 2024. 1. 23.

 

목차 

 

1. 문제상황

2. 문제 상세정의 과정

3. 문제 해결 

 

 

1. 문제상황 

 

Nice본인인증 Api 가 구글 크롬과 안드로이드에서는 정상 작동하지만 아이폰과 사파리에서는 405 method not allowed가 뜨면서 실패하는 상황 

 

*부가적인 문제상황 

1) 해외에서 쓰는것이 아니다보니 영어로 검색해도 해당 레퍼런스가없다.

2) 나이스 api 측에 전화해서 문의해도 레퍼런스가 없다는 답변 

3) Next 13.4 버전 에서 발생했으나 추후 해결 한 것으로 봐선 버전이랑은 크게 연관이없다는 게 내 생각이다. 

 

 

일단 검색했을때 이 문제에 대해서 해결방안이 적혀있는곳이나 힌트를 전혀 찾지 못했음으로 누군가에게 도움이 되길바라는 마음으로 이에 대한 글을 남겨둔다. 

 

문제해결방법을 보고싶다면  3. 문제해결로 바로 점프하시길 

 

 

 

2. 문제 상세 정의 과정 

- 에러 요인 추측 

 

1. 처음에는 Next.js 아니면 빌드 문제라고 생각했다. 

 

일단 빌드문제라고 추측했던 이유는  header를 보니 에러는 cloudfront 로 부터 나고있다고 뜨고있었기에 나는 이게 클라우트 프론트에서 리다이렉트 설정을 잘못한건아닌가 하고 추측하게되었는데   vercel로 배포 해보니 여전히 문제가 해결되지않아서 배포측 문제는 아니라고 판단되었다.

 

cloudFront설정이나 각종 리디렉션 설정도 다 만져보았지만 아무런 효용이없었다. 

 

Next.js문제라고 생각한건 405 method not allowed 라고 뜨는 화면 인터페이스 자체가 Next.js 의 인터페이스였기때문에 그 이전에도 빌드나 개발을 진행하면서 하면서 수도없이 깃헙 이슈를 들락날락거리면서 "젠장 Next.js 또 너야?" 하는 생각이 계속 들었기때문에 약간의 피해의식과도 같은 어떻게 보면 아주 합리적인 의심의 수순이였다. 

 

하지만 Api Route를 통해 통신한것도아니고 redirect 를받는데 405 라는건 말이안된다고 판단해서 나는 이때까지만해도 Nice Api의 문제인가 하고 있었다. 

 

 

2. 왜 사파리와 아이폰에서만? 

 

문제 상황에서 적었다 시피 Nice api 측에 전화해서 물어보니 레퍼런스가 없다는 답변을 받았다. 

 

문제 해결을 위해 

백엔드팀원에게 물어봐서 Nice본인인증 과정에서 우리 백엔드 API 값이 어디까지 들어오고있는지 확인했고 return URL은 뱉고있지만 그 다음 단계의 decoding에는 접근도 안한다는것으로 보니 이 에러가 백엔드에서 나는 에러가 아니라고 생각했다.  

 

사파리 콘솔을 보니 return 값에는 enc_Data 나 기다 데이터들은 들어오고있었다. 

 

이쯤에서 왜 GPT한테 물어보니 사파리나 아이폰등에서는 리다이렉트시  HTTP 메서드를 수정할수있다는 답변이왔는데. 나는 그냥 이걸 할루시네이션 정도로 취급했다. 

 

 

3. 라우팅 

 

 

잠깐 모든 프레임워크가 맡고있는 자동적인 부분에 대해서 생각하고 조급함을 버리기로했다.

 

그렇게 생각하니 하나하나가 다 힌트로 다가왔다.

 

405라는 에러 페이지는 왜 페이지에 노출된 걸까?  에러는 도대체 어느 API 에서 발생하는것인가? 처음에는 요청 부분에 클라이언트 측 URL/nice 가 떠서 나는 당연히 api 요청이라고 생각하고 디버깅을 했지만 내 발상의 한계였음을 깨달았다.

 

에러 '페이지' 라고 생각하고있으니 라우팅에대해서 생각하게되었다.

 

아주 오래전 SSR 은 API 통신하듯 라우팅이 이루어졌을것이다. (물론 지금도 내부에선 그렇게 동작하겠지만)

 

그렇게 자연히 이 에러가 넥스트 js라는 프레임워크가 알아서 라우팅 과정에서 생긴 에러라는것이겠구나 하는 추측에 도달했다. 

 

확인해야될건 사파리가 정말로 GET이 아닌 POST로 페이지를 요청하는가 였는데 

 

사파리 콘솔을 보니 정말로 POST로 페이지를 요청 하고있었다.

 

페이지 라우팅 요청이 POST로 가다보니 이 페이지에 대한 요청은 POST만 허용한다는 이야기라서 405가 뜨는구나!

 

그렇게 이해하니 바로 해결방법이 떠올랐다.

 

 

3. 문제해결  

 

문제 상세 정의 과정에서 이미 파악한대로의 문제라면

 

해결방법은 다음과 같다. 

 

사파리나 아이폰에서 보안적인 문제(로 추측된다)때문에 멋대로 HTTP method를 바꿔서 보낸다면.  Nice Api return 값을 클라이언트 측 라우트가 아니라  클라이언트 Next 서버로 바꾸고 우리 서버에서 각각 GET과 POST에 대한 리다이렉트 처리를 해주면 되는것이였다.

 

더 줄여서 설명하자면 

 

 백엔드 Nice Api return Url 을 클라이언트측 페이지로 바로보내는게 아니라 Next.js서버를 거쳐서 한단계 변환 과정을 거쳐 다시 우리 클라이언트 리다이렉트한다.  

 

클라이언트 측  서버 처리를 할려면 api Route에 대한 이해가 있어야되는데  개인적으로 Next js 에서 꼭 기능적인 활용 외에도 모킹 용도로도 상당히 쓸모있으니 개인적으로 써보길 추천한다. 

 

Nice Api return 값은 예를 들면 다음과 같다.  www.도메인/api/nice/test

 

return 값에는 알다시피 encData와 ~~ 가있다. 그것을 추출해야되는데 문제는 사파리와 아이폰의 POST 요청이다.

 

POST 요청으로 바뀐것 뿐만아니라 URL 자체에 노출되어있던 쿼리파라미터들이 전부 바디로 들어가게되는데. 잘 보면 application/json 이 아니고 폼 데이터 형태인것을 알수있다.

 

그래서 body를 변환할때 json이 아니라 폼데이터로 변환해야되며 추출하는 과정도 조금은 다르게 생겼다. 

 

내 폰이 아이폰이 아니라서 이게 될까 하고 반신반의 했는데 아이패드나  다른 사람의 아이폰으로 해봤을때도 아주 잘 동작했다. 

 

 

에러에 맞추다보니 오히려 어떻게 보면 보안적으로도 아주 안전해보이는 방법이된것같다는 생각이들었다.

물론 해결하기전까진 그저 개빡치는 뭔가였을 뿐이지만  

 

import { NextRequest, NextResponse } from 'next/server'

 

export async function POST(req: NextRequest) {
const body = await req.formData()

 

const token_version_id = body.get('token_version_id')
const enc_data = body.get('enc_data')
const integrity_value = body.get('integrity_value')

 

return NextResponse.redirect(
`${process.env.NICE_REDIRECT_URL}/nice?token_version_id=${token_version_id}&enc_data=${enc_data}&integrity_value=${integrity_value}`,
302,
)
}

 

export async function GET(req: NextRequest) {
const searchParams = req.nextUrl.searchParams
const tokenQuery = searchParams.get('token_version_id')
const encQuery = searchParams.get('enc_data')
const integirtyQuery = searchParams.get('integrity_value')
 
return NextResponse.redirect(
`${process.env.NICE_REDIRECT_URL}/nice?token_version_id=${tokenQuery}&enc_data=${encQuery}&integrity_value=${integirtyQuery}`,
302,
)
}

 

 

4. 배운 점 

1. 리다이렉트 처리를 할때 아이폰과 사파리는 get요청을 post 요청으로 바꾼다.

2. 바꿀때 formdata 형태로 변환해서 보낸다. 

3. 서버사이드 의 동작과 라우팅에 대해서 다시한번 복기

4. 블로그 글은 윈도우로 쓰다보니 사파리 콘솔 보는법이나 어떻게 유추했는지에 대한 과정을 글로밖에 쓸 수 가없어 아쉽고 더 좋은 기술적인 글을 쓰기위해서 평소에도 해결 과정을 작성하고 고민들을 적어놔야겠다는 생각이들었다.