본문 바로가기

대가리 쪼개기/Photon 대가리 쪼개기

Photon Chat Webhook 대가리 쪼개기 002 - 1 AWS lightsail로 웹훅서버 구축하기

반응형

ㅠㅠ 혼자 이것저것 트라이해보는것 보다 블로그 정리가 생각보다 피로도가 상당하네요.

후딱 후딱 빠르게 가보겠습니다.

 

 

당연한거지만, aws console에 로그인해주신 후, lightsail 서비스로 이동해주시기 바랍니다.

 

 

 

 

 

 

인스턴스 탭의 인스턴스 생성을 클릭!

 

 

 

 

 

LAMP 패키징을 사용하겠습니다. PHP 버전 7.4 이상이면 됩니다.

인스턴스는 가장 저렴한 플랜으로, 

인스턴스 이름이나 SSH키는 적당히 계정 상황에 따라서 선택해주세요.

모든 선택사항들을 선택하신 후 생성을 눌러주시고, 잠깐 흡연자 분들은 한대 태우시고, 아니신 분들은 차 한잔 하시죠.

 

 

 

 

 

ㅎㅎㅎ;;; 차 한잔 한다는게 롤토체스를 한 판 해버렸네요 ㅎㅎ;;;;;;

인스턴스가 생성이 완료되었으니, 커맨드 창을 띄워봅시다.

제가 이런 웹훅 테스트를 하고자 사용하는 (정확히는 포톤서비스 테스팅을 위해 간단히 만들게 되었습니다.)

PHP 소스코드가 있어서 그걸 클론해볼까 합니다.

 기본적으로 접속시 홈디렉토리로 접속되는데, 홈디렉토리 하위의 htdocs에 웹루트가 위치하게 됩니다만,

아무래도 상관 없습니다. 일단 웹루트로 이동해볼까요?

cd htdocs

 

htdocs 내부에 index.html 파일 하나 달랑 있는걸 확인 하실 수 있습니다.

한 번 http://{인스턴스 아이피주소} 로 접속을 해보시면...

 

 

 

 

 

 

 

네, 이런 화면이 나오는걸 확인 하실수 있습니다...

음... 다시 홈디렉터리로 이동해볼께요 

cd ~

 

웹훅 서버 소스코드가 위치할 적당한 디렉터리를 생성해주시기 바랍니다.

전 app으로 생성할께요.

mkdir app
cd app

이후에,

huntmori/php-simple-webhook-tester: php webhook tester using Flight (github.com)

이 저장소의 소스코드를 클론 할겁니다.

 

 

 

 

 

버튼을 눌러 깃 주소를 복사해주세요.

그 후에 클론을 합시다.

git clone https://github.com/huntmori/php-simple-webhook-tester.git

 

그 후 조회를 해보시면, 클론한 프로젝트 디렉토리가 생깁니다. 그 디렉토리로 이동해주세요.

그리고 디렉토리 내용을 한번 조회해봅시다.

cd php-simple-webhook-tester
ls -la

 

 

 

 

 

 

 

일단 먼저 해야 할 것은, 의존성 설치입니다.

php는 composer 라는 의존성 관리 도구를 사용합니다.

php 라이브러리 의존성을 관리해주는 도구인데요, 원래는 설치를 해서 사용하지만

편의를 위해서 프로젝트 루트에 넣어놓았습니다.

혹여나 의심스러우신 분들께서는 composer를 직접 설치하셔서 사용하셔도 무방합니다.

composer.json 에서 의존성을 읽어 필요한 라이브러리를 설치하게 됩니다.

다음 명령어를 실행해주세요.

./composer.phar install

 

 

 

 

 

 

그럼 위와 같이 다운로드와 설치가 진행되는 것을 확인하실 수 있습니다.

그 후엔 아파치 서버를 중지시킬겁니다.

엥? 왜요?

구름ide로 테스트하면서 느낀건데...웹서버 설정에 따라 너무 다양한 변수가 많은편이라..

php에서 제공되는 내장 서버로 테스트하는게 훨씬 편한 경우가 많다고 느껴져서 그렇습니다.

제 기억에는 aws lightsail같은 경우 무난하게 동작했던것 같지만... 나중엔 또 어떻게 바뀔지 모르잖아요..

내장서버로 테스트를 진행해보겠습니다.

일단 다음 명령어로 아파치 서버를 중지시켜보겠습니다.

 

sudo /opt/bitnami/ctlscript.sh stop apache

'Stopped apache' 가 나오면 정상적으로 가동이 중지된겁니다.

이번엔 php 빌트인 서버로 웹훅 서버를 가동시켜보겠습니다.

 

~/app/php-simple-webhook-tester$ sudo ./serve

위 실행파일을 실행시키면, 'PHP X.X.XX Development Server( http://0.0.0.0:80) started 란 메시지 출력과 함꼐 웹서버가 가동됩니다.

백그라운드로 실행하고자 할 경우, 끝에 &를 붙입니다. (로그 확인을 위해, 백그라운드 실행을 추천드립니다)

~/app/php-simple-webhook-tester$ sudo ./serve &

 

http://{인스턴스ip주소} 로 접속했을시

{"bye":"guys"} 라고 나오면 정상적으로 구동되는 상태입니다.

 

 

 

백그라운드로 실행되고 있는 serve를 종료시키고자 할때

serve 프로세스를 찾으려고 하면 정상적으로 종료시킬 수 없는데요, 
왜냐면 serve 파일 자체가 php 명령어로 이루어진 파일 이기 때문입니다.

 다음 명령어로 실행시키면, 실제 php 빌트인 서버를 실행시키고 있는 프로세스를 찾을 수 있습니다.

ps -ef | grep index.php

실제 php 내장서버를 실행하고 있는 프로세스

더 이상 웹서버 실행을 원치 않으실 경우 저 프로세스를 종료시키시면 됩니다.

 

 

 

 

정확한 동작 및 커스텀을 위해선, index.php를 살펴보아야 합니다.

index.php 파일을 한번 살펴볼께요.

 

 

 

 

 

 

<?php
    require_once __DIR__."/vendor/autoload.php";

    use Monolog\Handler\StreamHandler;
    use Monolog\Logger;
	use flight\net\Request;
	use flight\net\Response;

    class Controller {
		function loggingMethod(Request $requestObject, array $responseObject): void {
			if (is_dir('./logs') === false ) {
				mkdir('./logs', 0755, false);
			}

			$logger = new Logger('logger');
			$logger->pushHandler(new StreamHandler('./logs/'.date('Ymd').'.log'));
			$logger->info("[".$requestObject->url."]");
			$logger->info("request-query=========================================================================");
			$logger->info(json_encode($requestObject->query));
			$logger->info("request-body==========================================================================");
			$logger->info(json_encode($requestObject->data));
			$logger->info("response==============================================================================");
			$logger->info(json_encode($responseObject));
			$logger->info("======================================================================================");
		}

		function schemeMethod(Request $requestObject): void {
			if (is_dir('./scheme') === false ) {
				mkdir('./scheme', 0755, false);
			}

			$fileName = str_replace('/', '.', $requestObject->url);
			$schemeFileExsist = file_exists("./scheme/$fileName.json");

			if (!$schemeFileExsist) {
				$output = fopen("./scheme/$fileName.json", "a");
				fwrite($output, json_encode($requestObject->data));
				fclose($output);
			}
		}

		function chatWebhookCallBack(): void {
			$request = Flight::request();
			$baseResponse = array("ResultCode"=>0, "DebugMessage"=>"OK");
			Flight::json($baseResponse);

			$this->loggingMethod($request, $baseResponse);
			$this->schemeMethod($request);
		}

		function punWebhookCallBack(): void {
			$request = Flight::request();      
			$baseResponse = array("ResultCode"=>0, "ErrorCode"=>0);        
			Flight::json($baseResponse);

			$this->loggingMethod($request, $baseResponse);
			$this->schemeMethod($request);
		}
	}

    $controller = new Controller();
    Flight::route("POST /api/v1/chat/*",        array($controller, 'chatWebhookCallBack'));
    Flight::route("POST /api/v1/pun/room/*",    array($controller, 'punWebhookCallBack'));

    Flight::route('*', function(){
        Flight::json(array("bye"=>"guys"));
    });

    Flight::start();

 

중요한 부분은, 최하단의 몇줄입니다.

 

    Flight::route("POST /api/v1/chat/*",        array($controller, 'chatWebhookCallBack'));
    Flight::route("POST /api/v1/pun/room/*",    array($controller, 'punWebhookCallBack'));

포톤 웹훅은 아쉽게도, POST 요청으로만 오며, restful 하게 구성 할 수가 없습니다.

리퀘스트 라우팅 하는 부분이라고 보시면됩니다. 즉, 다른 경로로 받고자 한다면, 저 부분을 수정해주시면 됩니다.

 

 

    Flight::route('*', function(){
        Flight::json(array("bye"=>"guys"));
    });

 원래는 어떤 유형의 요청들이 들어오나 모니터링 해보려고 요청을 그대로 응답에 넣어 보는 형태로 구성을 했었는데,

생각보다 많은 무작위 공격이나 악의적인 요청이 들어오고 있어서, 임의로 제가 정의하지 않은 다른 모든 요청은 {"bye":"guys"}를 출력하도록 정의 해놓았습니다.

 

드디어 서버 설정이 끝났네요.

 

반응형