[트러블슈팅기] CSR에서 동적 OG 메타태그 적용하기

Dec.21.2023 이주영

AWS Web Frontend

이 글은 Client Side Rendering(CSR)과 CSR 시 인프라 구성환경 중 AWS CloudFront+S3 조합에서의 트러블슈팅기입니다.

OpenGraph(OG) 가 뭐지?

글을 시작하기 전에, OpenGraph(OG)가 익숙하지 않으신 분들을 위해서 스크린숏 하나를 보여 드리겠습니다.

요즘 웹페이지 주소를 공유하면 잠시 후 그 밑에 이미지와 문구가 표현되는 것 보셨으리라 생각합니다. 이 이미지와 문구들은 공유한 주소에 접근한 후, 그 페이지에서 양식에 맞는 정보를 추출해냅니다. 그 양식이 바로 OpenGraph(OG)입니다. 이제 OG가 혼란스럽지 않으시죠? 자, 이제 그럼 트러블슈팅기 속으로 들어가보시겠습니다.

이 글을 쓰게 된 이야기!

"오! OpenGraph(OG) meta tag를 동적으로 넣을 수 있어야 된다고요?"
최근에 공유하기 링크생성 작업을 하게 되면서 요청받은 내용이었습니다. 생성된 공유하기 링크를 SNS나, 문자메시지에서 보내면 OG meta tag를 통해서 이미지가 동적으로 바뀌어야 하는 요구조건이 있었습니다.

이게 왜 문제지?라고 생각하시는 분들을 위해서 간단하게 배민우리동네팀의 프론트엔드 기술스택을 소개하도록 하겠습니다.
배민우리동네는 초기에 빠른 Minimum Viable Product(MVP) 개발, 서버관리의 부담을 줄이기 위한 목적으로 Vite(Vite | 차세대 프런트엔드 개발 툴) 기반으로 CSR 웹애플리케이션을 제작하였습니다. 차후 Next.js로 마이그레이션 계획은 있지만 OG meta tag를 위해서 기술 스택을 변경할만한 사안은 아니었습니다. 그래서 현재 환경에서 가능한 방법을 찾기 시작했습니다.

다시 문제로 돌아오면, 현재 CSR 환경에서는 아래의 예시와 같이 정적인 HTML 파일이 모두 동일하게 유저에게 전달됩니다.

<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, viewport-fit=cover" />
        <title>HTML 예제</title>
    </head>
    <body>
        <div id="root"></div>
        <script type="module" src="/src/main.js"></script>
    </body>
</html>

여기서 문제가 생긴 것이죠. OG meta tag는 HTML 파일의 head 내부에 메타 태그의 형식으로 들어가야 합니다.

<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, viewport-fit=cover" />
        <meta property="og:title" content="[배민우리동네] 여기를 추천해요!" />
        <meta property="og:description" content="우리동네 정보부터 혜택까지!" />
        <meta property="og:image" content="https://baemin.com/baedal.jpg" />
        <title>HTML 예제</title>
    </head>
    <body>
        <div id="root"></div>
        <script type="module" src="/src/main.js"></script>
    </body>
</html>

요구사항에 따르면 위에 ‘og:image’ 메타 태그의 content 값을 동적으로 변경해 주어야 합니다.
하지만 CSR에서는 위 코드가 고정이기 때문에 무조건 정적으로 동일한 내용을 유저가 보게 하거나, 다른 도움 없이는 OG meta tag를 동적으로 구현할 수가 없는 것이죠.

결론적으로는 참 난감한 요구사항이었습니다.
하지만 배민우리동네팀이 사용하고 있던 인프라 환경에서 한줄기 희망이 보였습니다.

시작 전엔 완벽했던 계획

다행히도 배민우리동네 웹애플리케이션은 AWS 인프라를 사용하고 있습니다. 좀 더 자세히 말씀드리면, CloudFront와 S3를 이용하는 매우 정석적인 방법을 사용하고 있습니다.

CloudFront에서는 엣지함수라는 것을 사용할 수 있는데, AWS Docs(함수를 사용하여 엣지에서 사용자 지정, Amazon CloudFront 개발자 안내서)에서 설명하는 엣지함수의 역할은 간단히 아래와 같습니다.

Amazon CloudFront를 사용하면 자체 코드를 작성하여 CloudFront 배포에서 HTTP 요청 및 응답을 처리하는 방법을 사용자 지정할 수 있습니다.

위 설명처럼 엣지함수를 활용해 응답을 처리하는 방법을 직접 지정하여 아래와 같이 문제를 해결하려고 하였습니다.

원본 출처: AWS Docs

  • 위 도식도에서 보면 유저에게 4-viewer response를 통해 최종 결괏값인 HTML파일을 전달하게 되는데, 이 파일에 OG meta tag를 추가한 다음 리턴하는 것으로 수정하면 간단히 해결될 것이라 생각했습니다. 즉 ④-Viewer response 에서 함수를 추가해서 HTML을 동적으로 수정하는 방법을 구상하였습니다.

그래서 초기에 생각했던 흐름은 아래와 같습니다.

  1. 공유링크를 생성할때 링크에 query parameter 형태로 이미지 주소에 대한 정보를 삽입한다.
  2. ④-Viewer response 스텝에서 엣지 함수를 실행시킨 후, 파싱한 query parameter 정보를 활용해서 OG meta tag 정보를 생성한다.
  3. 생성한 OG meta tag 정보로 Origin server 혹은 CloudFront cache에서 넘어 온 HTML을 수정한 후 유저에게 전달한다.

계획은 완벽해 보였고, 어렵지 않게 해결할 수 있을 것이라 생각했습니다.
하지만 계획과 현실은 달랐습니다.

선택의 기로

사실 이 부분은 트러블은 아닙니다. 하지만 이후에 진행되는 트러블슈팅을 설명하는데 도움이 되실 수 있어서 간단히 소개 하고자 합니다.

CloudFront의 엣지함수는 두가지 종류가 있습니다.

  • 출시 된지 10년이 되가는 관록의 Lambda@Edge
  • 출시 된지 2년여 밖에 되지 않은 젊은피 CloudFront Functions가 있습니다.
기능 CloudFront Functions Lambda@Edge
장점
1. 성능과 효율성 매우 빠른 실행 시간과 낮은 지연 시간, 경량 작업에 이상적 다양한 런타임과 외부 라이브러리 지원, 복잡한 애플리케이션 로직 구현 가능
2. 비용 효율성 비용이 적게 들며, 작은 함수에 대해 매우 저렴함
3. 보안 VPC, 파일 시스템, 외부 네트워크에 액세스 불가, 보안 강화 다른 AWS 서비스와의 통합 가능, 더 강력한 애플리케이션 구축 가능
단점
1. 기능 제한 외부 라이브러리나 NPM 패키지 사용 불가, 기능적으로 제한적 비용이 더 높음, 특히 높은 트래픽과 복잡한 함수의 경우 비용 상승 가능
2. 실행 시간 제한 매우 짧은 실행 시간, 복잡하거나 시간이 많이 소요되는 작업에 부적합 초기 실행 지연 (냉동 시작) 시간이 있을 수 있음, 자주 사용되지 않는 함수에서 지연 발생 가능
3. 리소스 제한 제한된 CPU 및 메모리 리소스, 리소스 집약적인 작업에 부적합 보다 복잡한 보안 및 관리 고려사항, 외부 라이브러리 사용 시 보안 취약점이나 관리 문제 발생 가능

현재 저희 요구사항을 기준으로 불필요한 조건으로는 아래와 같습니다.

  1. HTML 변조과정에서 필요한 정보는 모두 Query parameter로 넘어올 것이기 때문에, 외부 네트워크에 접근할 필요가 없음.
  2. 간단한 변경작업이기 때문에 외부 라이브러리 사용 및 큰 리스소 불필요.

정리한 것처럼 현재 저희에게는 CloudFront Functions가 더 적합하였습니다.

하지만 결국엔 Lambda@edge를 선택하게 되었었는데, 이유는 아래와 같습니다.

CloudFront Functions 공식 Docs에서는 아래와 같이 써 있었고,

함수는 CloudFront 캐시 또는 오리진에서 반환된 원래 본문에 액세스할 수 없습니다. (참고: CloudFront 함수 이벤트 구조, Amazon CloudFront 개발자 안내서)

Lambda@edge Docs에서는 아래와 같이 씌어 있습니다.

원본 응답 이벤트에서 HTTP 응답의 본문을 바꾸거나 제거할 수도 있습니다.
(참고: Lambda@Edge 예제 함수, Amazon CloudFront 개발자 안내서)

저희의 계획은 HTML을 수정하는 것이었기 때문에 본문에 접근할 수 있어야 했고, 그렇기 때문에 Lambda@edge를 선택할 수 밖에 없었습니다.

시간이 흐른 후 이 결정이 ‘본문을 바꾸거나 제거할 수도‘ 라는 설명을 크게 잘못 이해한 후 도출한 결과 였다는 사실을 깨달았습니다.

엇! 내 로그는 어디에?

‘도대체 뭘 잘못 이해했다는 거야?’ 라며 궁금하신 분이 있으시겠지만. 그것에 대한 내용은 잠시 후에 다루기로 하고, 문제 해결 흐름에 따라 엣지함수 로그에 대해 겪었던 트러블에 대해서 먼저 나누려고 합니다.

테스트를 하면서 필연적으로 하는 것은 로그확인 입니다. 기존에 Lambda를 사용한 경험이 있어서 같은 방식으로 로그를 확인할 수 있을 것이라고 생각했는데, 로그가 전혀 찍히지 않았습니다. (사실은 로그를 잘못된 곳에서 찾고 있었습니다.)

Lambda@edge는 별도의 콘솔이 화면이 존재하는 것이 아니라 Lambda의 콘솔 화면을 공유합니다.

보통 Lambda를 사용 할 때 로그를 확인하는 방법은 아래와 같습니다.
Lambda 콘솔 메뉴에서 Monitor 메뉴안에 View CloudWatch logs 라는 버튼이 있습니다.

위 버튼을 클릭하면 로그를 확인할 수 있는 CloudWatch 화면으로 이동합니다. Lambda의 로그 스트림을 확인할 수 있는 페이지로 한번에 이동을 하는데요, 이 때 로그 그룹의 이름은 아래와 같은 형식을 갖습니다.

/aws/lambda/[lambda의 함수명]

예를 들어, 저는 Lambda 함수명을 ‘meta-adder’ 라고 지었는데요, 그렇다면 CloudWatch에서 ‘/aws/lambda/meta-adder’ 로그그룹에서 로그들을 확인할 수 있습니다.

여기서 한 가지 더 생각해 봐야 할 것은 Region 입니다.
Lambda@edge 함수를 연동하려면 Lambda를 생성할 때 AWS의 Region을 N.Virginia 리전(us-east-1)으로 설정해야 합니다. 다른 Region에서 연동할 수 없습니다. 따라서 위의 ‘View CloudWatch logs’ 버튼을 클릭하면 N.Virginia Region에서 로그를 검색하게 됩니다.

여기에서도 Lambda@edge 함수들의 로그를 확인할 수는 있습니다. 단, 콘솔 내에서 테스트 시 발생한 로그들입니다. 위 스크린숏 Test 섹션에서 ‘/aws/lambda/[Lambda의 함수명]’의 네이밍 패턴을 가지고 있는 로그 그룹에서 확인할 수 있습니다.

CloudFront에서 실행된 Lambda@edge 함수의 로그들은 완전히 다른 곳에 존재합니다.
첫 번째로 확인해야 하는 것은 Region입니다. Lambda에서 작성한 함수들이 Cloudfront에 배포되고 그 안에서 실행되기 때문에 AWS Docs에서는 CloudFront가 실행되는 Region에서 확인해야 한다고 안내하고 있습니다.
즉, 한국에서 사용하는 경우는 CloudFront가 서울 Region에서 실행이 될 것이기 때문에 이 Region의 CloudWatch에서 확인해야 합니다.

또한 로그그룹의 이름도 달라지고, 아래와 같은 패턴을 갖습니다. 위의 패턴과 형식이 많이 다르죠.

/aws/cloudfront/LambdaEdge/[CloudFront id]

예를 들어 CloudFront의 id 가 ‘E3PAVEWQJMMLFS’ 일 경우 아래와 같이 로그그룹이 생깁니다. 여기에서 실제로 실행되는 로그를 확인할 수 있습니다.

정리를 하면 CloudFront에서 동작하는 Lambda@edge 함수의 로그를 확인하려면

  1. CloudFront가 동작하는 Region으로 변경한다.
  2. CloudWatch에서 CloudFront id를 가지고 검색한 다음 나오는 로그그룹 결과를 통해서 로그를 확인한다.

여러분들은 저와 같은 실수를 하지 않으시기를 바랍니다.

CloudFront Functions는 Lambda@edge와는 다른 로그확인 방식을 사용합니다. 다행히 더 간단합니다.
CloudFront가 실행되는 리전에 상관없이 N.Virginia 에서 확인합니다. 그리고 로그그룹 이름은 아래와 같은 패턴을 갖습니다.

/aws/cloudfront/function/[CloudFront function의 이름]

예를 들어 CloudFront function의 이름을 ‘client-request-handler’로 하였다면,
‘/aws/cloudfront/function/client-request-handler’ 로그그룹에서 로그를 확인하실 수 있습니다.

이렇게 로그를 확인할 수 있게 되면서 제대로 테스트를 할 수 있게 되었고, 곧 충격적인 사실을 마주하게 됩니다.

Body에 접근할 수가 없다

계획대로라면 ④-Viewer response 쪽 Lambda@edge 함수에서 HTML에 meta tag를 주입하여 유저에게 리턴하는 것이었습니다. 하지만 문제가 있었는데요, body를 함수에서 접근할 수가 없었습니다.

어? 분명히 아까 ‘원본 응답 이벤트에서 HTTP 응답의 본문을 바꾸거나 제거할 수도 있습니다.’ 라고 써 있는 AWS Docs 내용을 소개해 드렸는데 body에 접근할 수 없었다는 것은 무슨 뜻일까요?


위에서 보여드렸던 엣지함수 도식도를 다시 가지고 왔습니다.

사실 Lambda@edge 설정을 할 때 ‘include body’ 란 옵션이 있습니다. 하지만 이 body를 포함하는 옵션은 ①번, ②번의 경우에만 적용할 수 있습니다. 즉, request 함수 에서만 body를 포함시킬 수 있습니다.
유저가 body를 포함하는 request를 한 경우에만 요청에서 body를 확인하고 수정을 할 수 있는 것이지,
origin을 통과 하여 나오는 ③번, ④번 response에서는 body를 포함할 수 있는 방법이 없었습니다.

그렇다면 ‘본문을 바꾸거나 제거할 수도 있다’ 라는 건 무슨 뜻이었을까요?
여러 테스트를 거쳐 확인한 결과 저 설명의 뜻은 아래와 같았습니다.

Origin에서 넘어 오는 body는 참고할 수 없지만, response 함수에서 body 내용을 새롭게 교체하거나, 아예 삭제 하여 빈값으로 보낼 수 있다.

초기에 ‘바꾸다’ 라는 의미를 ‘수정할 수 있다’ 라고 오해를 하여 생긴 문제였습니다.

오해는 풀었지만, 큰 문제가 생겼습니다.
초기에 계획했던 동작인 Viewer response body를 조작하여 유저에게 리턴해줄 수가 없게 된 것입니다.

새로운 방법의 발견!

같은 팀에서 저와 같이 프론트엔드 개발을 함께하고 있는 시니어 개발자 송요창님께 도움을 요청하였습니다. 이때, 요창 님이 틀에 갇혀 있던 저의 생각을 끄집어 내주셨습니다.

그때 말씀해 주신 내용을 정리하였습니다.

"OG를 나타내기 위해서 필요한 값은 HTML안에 있는 header의 meta 태그들 뿐입니다. body에 실제 어떤 데이터가 있는지, 심지어 body에 데이터가 없더라도 아무 상관 없을 것입니다."


그래서 새롭게 낸 아이디어는 다음과 같습니다.

  1. ①-Viewer request에서 user-agent를 확인하고 bot의 접근이라면, ④-Viewer response에서 body를 OG meta tag들만 있는 HTML 파일로 교체(이 때, 기존의 body 내용은 참고하지 않습니다)하여 bot에게 리턴한다.
  2. 만약 ①에서 user-agent가 bot이 아니라면, ④-Viewer response에서 body를 교체하는 아무런 동작도 하지 않고 CloudFront cache 혹은 origin 에서 넘어온 데이터를 그대로 유저에게 전달한다.

여기에서 또 새로운 로직이 추가 되었는데요, 바로 user-agent로 최종 사용자가 bot인지 체크를 하게 됩니다. 그 이유에 대해서 간단하게 설명 드리겠습니다. 위에 새롭게 도출해낸 아이디어에서 보면 기존 bot일 때 HTML 파일을 교체합니다. 이 때, 교체된 HTML 파일은 Meta 정보를 위한 필숫값만 갖게 되고, 실제로 앱에서 필요로 하는 정보들은 모두 유실이 됩니다. 그래서 bot이 아닐 때는 origin에서 넘어온 원본 HTML을 넘겨 줘야 최종 사용자가 웹애플리케이션을 사용할 수 있습니다. 그래서 bot인지 유무를 확인하는 로직이 필요합니다.

Lambda@edge를 선택했던 이유는 body에 접근하기 위해서였는데, body에 접근할 수 없으니 CloudFront Function을 통해서 작업을 하기로 하였습니다.

이렇게 하면 드디어 문제를 해결할 수 있을 것이라고 생각하였지만, 순조롭게 흘러가지는 않았습니다.

Custom header 사라지다

①-Viewer request 함수에서 bot인걸 판단하면 ④-Viewer response 쪽 함수에서는 이 호출을 실행한 주체가 bot인지 어떻게 알 수 있을까요?

저는 위 문제를 해결하기 위해서 Custom header를 사용하기로 하였습니다. ①-Viewer request 함수에서 user-agent를 통해 bot 여부를 파악하고, isbot 이란 custom header에 ‘true’ 혹은 ‘false’ 값을 삽입하는 로직을 넣어서 테스트를 수행하였습니다.

하지만 곧바로 문제를 발견하였습니다.
그 문제는, ①-Viewer request에서 추가한 custom header가 origin 을 지나는 시점 부터는 사라진다는 것이었습니다. Custom header는 ②-Origin request 까지는 유지가 됩니다. 하지만 ③-Origin response 부터는 없어지는 것이죠. 현재 저희는 S3를 Origin으로 사용하고 있는데 리퀘스트에서의 Custom header를 origin이 받지만, Origin에서는 Response를 생성할 때 없어지고 있었습니다.

그렇다면 ④-Viewer response에서 직접 user-agent를 확인해서 bot인지 알 수 있을까요?
그것도 불가능합니다. 그 이유는 user-agent는 origin을 거치면서 origin의 user-agent로 변경됩니다. 그래서 response 쪽 함수에서 user-agent를 확인하면 S3 / CloudFront가 됩니다.

다시 길이 없어졌습니다. 모든 방법이 실패해서 엣지함수를 쓰는 방법은 포기해야 하나 생각을 했습니다.

최종시도, 그리고성공!

항상 모든 방법이 실패할 때는 마지막으로 공식문서로 돌아오는 습관이 있습니다.
이번에도 읽었던 문서를 세번정도 다시 읽었습니다.

읽고 있는데 제 눈길을 사로 잡는 설명이 있었습니다. 분명히 전에도 읽었던 부분인데 느낌이 새로웠습니다.

그 설명은 바로 엣지함수에서 트리거할 수 있는 CloudFront 이벤트에 관한 설명(링크)이었는데요, 아래 스크린숏을 가지고 왔습니다. (위 설명링크는 Lambda@edge 쪽의 설명이나 CloudFront Function 설명에서도 참고하는 자료로 사용하고 있습니다.)

출처: Lambda@Edge 함수를 트리거할 수 있는 CloudFront 이벤트, Amazon CloudFront 개발자 안내서

뷰어 응답 즉 ④-Viewer response가 실행되지 않는 조건 중에서 세번째 조건

최종 사용자 요청 이벤트가 트리거한 함수로부터 응답이 생성되는 경우

최종 사용자 요청 이벤트인 ①-Viewer request에서 바로 최종사용자(End user)로 응답이 생성될 수 있다. 그렇다면 ①-Viewer request에서 바로 유저에게 값을 전달하는게 가능할까?
한줄기 빛과 같은 문구였습니다.

이전까지 저는 ①-Viewer request의 흐름이 공식문서의 그림처럼 단방향으로만 흐르는줄로 알고 있었습니다. 하지만 저 문구를 봤을때 그게 아닐 수도 있다는 생각에 바로 테스트를 시작하였습니다.

테스트 방법은 아래와 같습니다.
①-Viewer request에서 user-agent로 bot임을 판단하면, return 값을 아래와 같이 주었습니다.
만약 bot이 아니라면 기존과 같이 event.request를 return 하도록 하였습니다.

function handler(event) {
    var request = event.request;
    /**
    ** 로직들...
    **/
    if (isBot) {
        return {
            statusCode: 200,
            statusDescription: 'OK',
            headers: {
               'content-type': {
                    value: 'text/html'
                }
            },
            body: {
                encoding: 'text',
                data: result // OG meta tag 가 포함된 HTML
            }
        };
    }
    return request;
}

결과는 대성공!

최종 결과물은 아래와 같습니다.

  • ①-① Viewer request에서 만약에 bot이라면 다음 단계를 진행하지 않고 바로 ①-②로 리턴을 하면서 사이클이 종료가 됩니다.
  • bot이 아니라면 원래 순서대로 ①-① -> ② -> ③ -> ④ 진행되거나,
    CloudFront chche가 hit 되어있다면 ①-① -> ④ 의 과정을 거칠 것입니다.

이렇게 모든 것이 평화롭게 끝나는 줄 알았습니다.

아직 끝나지 않았던 이슈

이제 다 끝난 줄 알았습니다. QA를 시작하기 전까진 말이죠.
기획 요구사항에는 SNS뿐만 아니라, 문자메시지를 보낼 때에도 정상적으로 노출이 되어야 했습니다. iOS에서는 테스트 시 문제가 없었습니다. 그런데 안드로이드에서 문제가 생겼습니다.

테스트를 하는 안드로이드 기종은 갤럭시였는데, 사내 다른 서비스들은 OG정보가 잘 노출되는데 배민우리동네 서비스만 노출되지 않는 문제가 발생하였습니다.

로그부터 파악해 봐야 합니다. 기본 안드로이드 테스트 장비인 갤럭시가 OG태그를 가져오기 위해 접근한 로그 파악 성공. 그리고 이 로그에서 상당히 특이한 user-agent를 발견하게 됩니다.

Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0

기본적으로 갤럭시에서 장비를 통해 접근하면 아래와 같은 user-agent가 남습니다.

Mozilla/5.0 (Linux; Android 9; SM-G960N Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.134 Mobile Safari/537.36

모바일 브라우저 및 애플리케이션에서의 접근은 안드로이드 버전과 갤럭시폰의 코드명이 붙는데 반해서, OG태그에 접근한 bot은 다른 user-agent를 갖고 있습니다.

바로 이것이 문제가 되었는데요.

Viewer Request 엣지함수에서 bot을 탐지 하기 위한 Regular expression(regex)은 아래와 같았습니다.

var BOT_CHECK_REGEX = /googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|kakaotalk-scrap|yeti|naverbot|kakaostory-og-reader|daum/i;

테스트한 다른 환경에서는 위 regex를 통해 모두 bot으로 판별이 되었는데, 갤럭시에서 접근할 때 사용한 user-agent는 판별할 수가 없었던 것입니다.
여러 번 테스트 끝에 ‘X11’ 을 regex에 추가 하여 갤럭시 문자메시지창에서의 문제를 해결하였습니다.

위 문제를 해결하면서 새롭게 알게 된 사실이 있습니다.
보통 여타 SNS서비스들 및 iOS는 링크를 입력하게 되면 OG태그를 위한 접속 및 파싱 등의 작업을 서버에서 하고 결과를 클라이언트에 내려 노출하는 식으로 동작을 합니다.
하지만 갤럭시 문자메시지는 클라이언트인 폰자체가 OG태그 정보를 얻기 위해서 사이트에 접속하고 직접 파싱하여 정보를 노출하고 있는 것을 확인하였습니다.

또한 이 기능은 안드로이드의 기본 기능이 아니라 삼성에서 자체적으로 넣은 것으로, 옵션에서 해당 기능을 켜고 끌 수 있었습니다. 그리고 이런 기능을 넣지 않았던 단말기들(LG 스마트폰 등)은 OG정보를 볼 수가 없었습니다.

이렇게 모든 문제가 평화롭게 해결되었습니다.

글을 마치며

항상 예상과 다르게 흘러가는 작업들을 보면서 다른 분들은 저와 같은 실수를 하지 않았으면 하는 바람에 트러블슈팅기를 나누어 보았습니다.

사실 위에서 기술한 것보다 더 자잘한 이슈들도 더 있었습니다.
특히 CloudFront는 기본적으로 캐싱을 하기 때문에, 내가 테스트한 결과값이 제대로 반영이 안되었을때 매우 혼란스러웠습니다. 나의 새 코드가 아직 캐시에 반영이 안 된 것인지, 혹은 로직상의 문제인지 확인하기가 쉽지 않았습니다. 캐시가 Invalidation되는 시간을 정확히 알수 없던 것도 한몫 했습니다.

이 글이 여러분들의 개발작업에 조금이라도 도움이 될 수 있길 바라며 글을 마치겠습니다.