어? 혹시... 정지..?

최봉수·2023년 11월 28일
0
post-thumbnail

데이터도 잘 불러와서 금방 끝날 줄 알았다.
하지만, 역시 그럴리 없지ㅋㅋ
버그만 생기면 다행인데 꽤나 크리티컬한 이슈도 생겨버렸다.

이슈

동일 출처 정책(SOP)



데이터로 받아온 url을 html에 출력하려고 했을 때 해당 이슈가 발생했다.
이미지에도 보안 정책이 걸려있을 줄은 몰랐다.
구글링과 GPT 선생님을 통해 해답을 찾았다.
서버에서 image url을 클라이언트로 보내서 바로 노출시키는게 아니라 서버에서 base64로 변환하여 클라이언트에 노출시키면 된다.

방법을 알았으니 수정해보자

// index.js
async function getImageTag(url) {
	try {
		const request = fetch('/getImage', { headers: { url } });
		const response = await request;

		if (!response.ok) {
			throw new Error();
		}

		return await response.text();
	} catch (error) {
		console.error('Error from Client:', error.message);
	}
}

클라이언트에다가 서버에 요청할 새로운 함수를 추가한다. (사실 query에 넣어서 보내도 되지만 뭔가 저게 편해서 header에 넣었다.)

// server.js
app.get('/getImage', async (req, res) => {
	try {
		const response = await fetch(req.headers.url);
		const buffer = await response.buffer();
		const imageData = buffer.toString('base64');
		const contentType = response.headers.get('content-type');
		const base64 = `data:${contentType};base64,${imageData}`;
		res.send(`<img src='${base64}' alt="" />`);
	} catch (error) {
		console.error(`Error from Server: ${error.message}`);
	}
});

서버쪽 코드도 추가했다.
저 코드가 나오기 전에 URL.createObjectURL(), Canvas등 알고있는 방법으로 변환하려 시도했지만, 'maximum call stack' 등과 같은 에러가 발생해서 찾아보니 용량이 너무 커서 해당 이슈가 발생한다고 그런다.

지금까지 수정하고 보니 다 똑같은 로직을 도는데 불필요하게 쪼갤 필요 없이 서버 '/getFeedData' 엔드포인트에 데이터 필터링 반환 함수를 같이 던져서 '/getFeedData'에서 응답데이터를 필터링하고 이미지 변환까지 해서 던지면 더욱 더 간결해 질 거 같은 생각이 든다.

아, image url도 fetching해야해서 지금 유지가 더 나을라나? 이건 차근차근 고민해봐야겠다.

크리티컬 이슈 발생

IP 차단 의심

문득 테스트를 하던 중에 잘 나오던 데이터가 나오지 않는다.
스크린샷을 못찍어둬서 정확하게 기억은 안나지만 유효하지 않은 상태? 라는 에러 메세지였던 거 같다.
인스타그램 홈페이지를 들어가봤다.

응?

확인 결과 이슈 발생 케이스를 대략 특정할 수 있었다.

  1. 웹에서 발생한다.
  2. 'https://www.instagram.com/' 으로 접속하면 문제없다.(로그인 화면)
  3. 'https://www.instagram.com/user_name/' 으로 접속하면 발생한다.
  4. 비 로그인 상태에서만 발생한다.
  5. 로그인 상태에서는 문제없다.
  6. 폰에서 데이터로 접속하면 문제없다.
  7. 폰에서 작업하던 맥북과 동일한 wifi로 연결 후 접속하면 발생한다.
  8. 네트워크에선 302가 뜬다. (인스타그램에서 리다이렉트 시키고 있다)

확인 결과 위처럼 이슈 발생 케이스를 대략 특정할 수 있었다.
로그아웃 상태로 작업을 했기에 계정이 잠긴 것은 아니다.
proxy를 통해 로컬 서버 ip를 숨기고 작업한 것도 아니다.

그러면 가장 유력한 상황은 크게 2가지 같다.

  1. 너무 잦은 요청으로 ip가 일정 시간 차단 되었다.
    • 응답 성공 확인 후 mock data를 사용하지도 않아서 내 잘못이다.
    • 스케줄링을 통해서 특정 시간에 1번만 실행 후 로컬 json에 데이터로 저장해 fetch없이 local data를 보여주러던 작업을 생각만하고 안했다. 내 잘못이다.
  2. 보안 정책 위반으로 ip가 영구 차단 되었다.
    • 보안 정책 제대로 안 읽어본 내 잘못이다.

뭐가 됐던 내 잘못이 맞다.
하지만 이건 또 뭐지?

파훼법?

인스타그램에 로그인 했다가 다시 로그아웃을 하면 세션이 남아있는지 다시 정상적으로 접속이된다. (이슈 발생 케이스 #4, #5)

로컬/세션 스토리지를 싹다 지워도 보고 크롬 쿠키도 날려봤다.
그래도 유지 된다.... 왜? 도대체 왜?

쿠키는 지식이 없어서 아직 뭘 시도해보지는 못했다.
찾아보면서 쿠키 쪽을 건드려봐야겠다.
현재 Meta Cookie 정책에서 도움이 될 만한 정보는 아직 찾지 못하였다.

우선은 이미지 노출도 확인했으니 정확한 원인을 파악하기 전까지는 개발을 중단해야겠다.

profile
돈이 좋아

0개의 댓글