본문 바로가기

Trouble Shooting/episode 1. 네트워트 지연 에러

네트워크 접속 지연? (1) - REST API

최근 아이폰의 기능중에 단축어, 그 중 "자동화"라는 기능을 즐겨쓰고 있다.

 

특정 상황(기상할 때, 지정 건물 반경 300m를 정해둔 시간대에 도착할 때)의 조건이 형성되면 원하는 앱을 실행할 수 있다.

이를 통해 사옥에 출퇴근할때마다 출퇴근 어플이 켜지도록 만들어서 잊어버리지 않게 단축어를 만들었다.

 

만들다보니 생각난건 특정 페이지의 출석 체크 버튼에도 URL이 있으니

"이 URL을 특정 시간에 Safari앱을 통해 자동적으로 켜지게 해둔다면 편하게 날먹할 수 있지 않을까?"

라고 생각했다가 난관에 부딪혔다.

 

우선 출석 체크 버튼의 URL은 해당 페이지가 자동로그인을 지원하지 않기 때문에 얻는 게 불가능했다.

무조건 로그인이 되어 있어야 출석페이지가 나오므로 먼저 로그인 버튼부터 시작하기로 했다.

해당 페이지는 로그인을 할 때 네이버를 통한 서드파티 로그인을 지원하는 형태이고,

로그인을 하려면 "네이버를 통해 로그인" 이라는 버튼을 클릭하면 되므로 이 버튼의 URL을 얻으면 해결된다고 생각했다.

 

그러나...

 

문제점 1. 로그인 페이지에 시간 제한이 존재

 

해당 페이지에서 로그인 버튼을 눌렀을 때 팝업창이 뜨면서 네이버 로그인으로 연동되고

이 팝업창에서 뜨는 URL은 다음과 같았다.

`https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=PV3hpxvmtFk1LHyP4GqI&scope=login+userinfo&state=0df613b7ac2547de0e72d192cd6ac3be1847049a868b3c616c0e20cdd85c0011c946b3f6a32d25481d649a36c05679a821b152490dce31a78afa74c9eb6fbbf2972e47a29ef215282d9be4cfa265e8e8e49894f62c3e6eedf73c4c0671514b78a0295fa5b45d31b9b6d2c1ebd63e36a5c12f71840d242d08656ac801ef8a8cf2&redirect_uri=https%3A%2F%2F${domain}%2FApi%2FMember%2FOauth2ClientCallback%2Fnaver%2F`

 

이제 이 URL로 자동화를 등록하면 자동로그인은 될 것이라고 생각해서 적용 후 테스트 해봤지만

네트워크 접속이 지연되고 있습니다. 잠시후 다시 시도해주세요. [1005]

 

고객에게 제공되는 에러코드에 대한 정보를 따로 찾아볼 수 없어

위와 같은 오류에 대한 분석을 하고 문제점의 원인을 설명하고자 한다.

 

웹의 본질 : 요청(Request)과 반환(Response)

웹은 요청과 반환(응답)의 연속이다.

설령 각각의 주체가 바뀌더라도 이러한 방식은 계속된다.

클라이언트(나 - 웹 브라우저)가 어떤 웹사이트에서 어떤 정보를 얻고싶다고 요청한다면

서버(웹사이트에서 서비스를 제공하는 주체)가 이 정보를 반환해주는 형태이다.

 

이는 필시 사람 사이에서의 일과 다를 바가 없다.

한 손님이 한식 식당에 들어가 "김치찌개를 주세요." 라고 요청하면

식당의 직원은 이를 요청 받고 김치찌개를 만들어 손님에게 반환한다.

 

하지만 지구에 있는 모든 사람들과 식당의 요청과 반환방식은 제각각이다.

손님이 맵기 조절을 요청하거나, 단골이면 말없이 앉아서 늘 먹던 것을 달라고 할 수도 있다.

저희는 선불이에요 라고 말하는 가게도 있을 것이고 기본 반찬을 제공하지 않는 가게도 있을 것이다.

 

이는 웹에서도 마찬가지다. 각양각색의 요청과 반환 방법이 존재할 수 밖에 없다.

그렇지만 컴퓨터는 사람처럼 유연하게 대처할 수 없다. 하나의 약속된 방식의 필요성이 제기되었고,

이에 나오게 된 현재 많이 쓰이는 약속이 바로 REST다.

 

REST (Representational State Transfer)

REST는 네트워크에서 통신을 규정하는 하나의 지침이라고 생각하면 된다.

자세히 보면 6개의 원칙이 있고 이를 지켜서 만드는 API를 RESTful API(또는 REST API)라 부른다.

API에 대해서는 지금은 그냥 웹 서비스를 제공하는 하나의 소프트웨어라고 생각하자.

그렇다면 웹에서 요청과 반환은 어떠한 표현(Representation)일까?

사람의 커뮤니케이션으로 비유하자면 이렇다.

 

A를 해달라고 B에 요청하는것.
그런데 주실때는 C로 받게 해주세요.
다 하셨으면 D라고 얘기해주세요.

 

  • A를 해달라는 것은 다시 말해 어떤 행위를 요청하는 것이다. 프로그래밍에서는 CRUD(Create, Read, Update, Delete)작업에 해당되는 함수들을 많이 쓴다. 웹에서도 이 단어들의 뜻을 함의하는 POST, GET, PATCH, DELETE 등의 함수들을 사용한다. 이를 웹에서는 Method라고 한다.
  • B가 우리가 흔히 말하는 URL이다. 웹페이지에서 리소스가 있는 곳의 위치를 가리키는 문자열을 뜻한다. 조금 더 자세히 설명하자면, 단순히 namucy.tistory.com 같은 아주 짧은 주소만이 아니라 namucy.tistory.com/manage/newpost와 같이 정확한 리소스의 위치를 지정한다. 이때 /manage/newpost와 같이 세부적인 내용이 추가적으로 붙는데, 뒤로 갈수록 세부적인 범주이다. 
  • C는 요청 후 내가 반환받는 리소스(정보, 자원 등 모든 것)의 형태를 지정한다. 일반적으로 JSON이라는 javascript에서의 object의 형태로 받도록 요청한다.
  • D는 반환하는 주체(서버)가 나에게 주는 신호의 형태이다. 인터넷을 하다 보면 "HTTP 404 Not found" 라는 오류를 대부분 봤을 것이다. 여기서 HTTP 404가 앞서 말한 응답 신호의 대표적인 예이다. 다양한 response 코드가 있지만 크게 앞자리수 1 ~ 5를 기준으로 신호의 유형을 구분할 수 있다. 4로 시작하는 경우는 무언가 잘못됐고, 귀책사유가 나(클라이언트)에게 있다는 프로토콜이다. 앞서 예를 들었던 404 Not Found 와 같은 경우, 서버에는 없는(제공하지 않는) URL인데 사용자가 요청했을 때 나오는 오류이다.
더보기

참고로 위와 같은 요청-반환의 규칙을 HTTP(HyperText Transfer Protocol)이라 하고

이를 지키는 API를 HTTP API라고 한다.

정확한 정의의 REST API란 위와 같은 HTTP 요청- 반환의 규칙을 지키면서 RESTful한 API를 뜻하는 것이다.

따라서 HTTP API에 REST API가 포함되는 개념이라고 할 수 있다.

 

그러나 최근 REST API는 실용적인 측면에서 REST의 6개 규칙을 지키지 않는 경우가 많다. 

REST가 제공하는 것은 하나의 아키텍쳐 규칙일 뿐, 어떤 표준이 아니기 때문이다.
따라서 요즘에는 REST API와 HTTP API의 구분이 애매해졌고, 이를 혼용해서 쓴다.

HTTP 404 error 메세지창의 예시 중 하나.

 

 

 

문제점 1의 원인 분석

현재 상황 파악

이 상황에서의 서드파티 로그인(네이버를 통한 로그인)은 이러한 REST API라고 할 수 있다.

더 상세히 설명하자면 현재 페이지에서 로그인을 할 때는 두 개의 API를 사용하고 있다.

하나는 내가 사용하고자 하는 페이지의 API, 다른 하나는 OAuth2.0을 사용한 네이버 로그인 API이다.

이해를 위해 내가 사용하고자 하는 페이지의 API를 A1, 네이버 로그인 API를 A2라고 하겠다.

 

내가 이 페이지에 로그인을 하기 위해서 네이버로 로그인 버튼을 누르면 다음과 같은 과정이 진행된다.

  1. 현재 페이지에서 로그인하고 싶다(이 페이지에서의 서비스를 사용하고 싶다)고 A1에게 요청 한다.
  2. A1은 나에게 A2로 가서 로그인을 해오라고 반환하고, 친절하게 A2의 페이지(네이버 로그인 팝업)를 띄워준다. 이는  A1이 나에게 A2로 가서 권한을 얻어오라고 요청하는 것으로도 볼 수 있다.
  3. A2에서 네이버 로그인을 하면 A2에서 A1에 로그인할 권한을 얻는다. A1에게 요청 받았던 권한을 반환하는 형태로 볼 수 있다.
  4. 아까 받은 그 권한을 A1에게 보여주고 요청하면, A1이 서비스를 사용할 권한을 나에게 반환하는 것이다.

사실 위의 과정은 생략된 게 엄청많다. 이는 이후의 글에서 API와 OAuth2.0에서 설명하겠다.

하지만 지금은 흐름을 설명하고 문제점이 어디에서 일어나는지에 집중하겠다.

 

앞서 얘기한 URL의 팝업은 2에서 이루어지고,

내가 로그인하는 행위는 3에서 이루어진다.

 

그런데 만약 2에서 나오는 요청에 대한 권한이 3의 과정에서 한참 뒤에 형성이 된다면? 

 

첩보영화에 빗대어 표현하자면 주인공(잠입하는 에이전트)이 보안체크를 받는데

평소면 10초 안에 진행됐을 보안체크가 2분이 걸리면 보안요원 입장에서는 이 사람이 엄청 수상하다.

 

이 페이지에서도 마찬가지다. 내가 자동로그인을 하겠다고 예전의 URL을 통해 지금 로그인을 한다면

맞는 접근이긴 하지만, 요청에 대한 반환이 한참 뒤에 이뤄진 셈이 된다.

따라서 서버는 이를 "네트워크에 지연이 있다"고 판단하고 접근을 거부하는 것이다.

 

판단의 근거

예전에 받은 URL과 지금 글을 작성할때 받은 URL을 비교해보면 아래와 같다.

// 이전의 URL
`https://nid.naver.com/oauth2.0
/authorize?response_type=code&client_id=PV3hpxvmtFk1LHyP4GqI
&scope=login+userinfo
&state=0df613b7ac2547de0e72d192cd6ac3be1847049a868b3c616c0e20cdd85c0011c946b3f6a32d25481d649a36c05679a821b152490dce31a78afa74c9eb6fbbf2972e47a29ef215282d9be4cfa265e8e8e49894f62c3e6eedf73c4c0671514b78a0295fa5b45d31b9b6d2c1ebd63e36a5c12f71840d242d08656ac801ef8a8cf2
&redirect_uri=https%3A%2F%2F${domain}%2FApi%2FMember%2FOauth2ClientCallback%2Fnaver%2F`

// 지금 받은 URL
`https://nid.naver.com/oauth2.0
/authorize?response_type=code&client_id=PV3hpxvmtFk1LHyP4GqI
&scope=login+userinfo
&state=bec381a133b45cb3147030561afb4179c3ccae99bc124696d1635a1e62fcee232f4cf493e5c2590e99f6f2f0945c41808d998150ed785a15eb829a6f1959577507bc4fc24a65a0fc93352079f8f2395141be9e868a8b85f11fae547557d75d5d8b70a347ef2e3c92082ed1bed4ca0ef1dd9a72f6793c073eb00c1229e9306881
&redirect_uri=https%3A%2F%2F${domain}%2FApi%2FMember%2FOauth2ClientCallback%2Fnaver%2F`

 

이를 보면 state = 이후 부분이 명확하게 다른 것을 알 수가 있을 것이다.

나중에 OAuth2.0 관련 글에서 서술하겠지만, 권한 설정을 할때 실제로 timeout 세션을 다루는 게 있다. 

 

결론

위와 같은 과정을 통해, 페이지에서 제공하지 않으므로 네이버를 통한 자동로그인은 불가능 함을 알 수 있었다.

그렇지만 설명하지 못한 부분이 많다. 이후 드러나는 추가적인 문제점이 또 있다!

이는 API와 이것의 인터페이스, OAuth 2.0과 관련된 글에서 다루도록 하겠다.