본문 바로가기
IT/web

[PHP] curl GET/POST Rest API 인증, 요청 및 JSON 응답 처리 방법

by 어느해겨울 2022. 1. 6.

 

curl GET/POST Rest API 인증, 요청 및 JSON 응답 처리 방법

- php curl 요청(request) 및 응답(response)을 쉽게 처리할 수 있는 함수를 소개한다.

 

php 에서 Rest API 서버에게 요청과 응답을 하기 위해 php curl 을 사용한다.

php curl 사용 방법은 많지만 사용하기 쉽도록 함수를 만들어 보았다.

 

php curl의 오류 검증, HTTP response 의 response code 검증, json decode 검증을 통해 정상적인 JSON response 데이터인지 검증한다. 그리고 오류 시 각 상황에 맞는 HTTP code의 message로 JSON 데이터를 구성한다.

 

 

사용 방법은 아래 소스 코드를 참고하자.

 

https://github.com/muabow/home/tree/main/src/php/curl

 

GitHub - muabow/home: C/C++, PHP, GO source/library

C/C++, PHP, GO source/library. Contribute to muabow/home development by creating an account on GitHub.

github.com

 

 

소스코드 : func_curl.php

<?php
    function get_http_status_message($_status) {
        $arr_http_status = array(
                100 => 'Continue',
                101 => 'Switching Protocols',
                200 => 'OK',
                201 => 'Created',
                202 => 'Accepted',
                203 => 'Non-Authoritative Information',
                204 => 'No Content',
                205 => 'Reset Content',
                206 => 'Partial Content',
                300 => 'Multiple Choices',
                301 => 'Moved Permanently',
                302 => 'Found',
                303 => 'See Other',
                304 => 'Not Modified',
                305 => 'Use Proxy',
                306 => '(Unused)',
                307 => 'Temporary Redirect',
                400 => 'Bad Request',
                401 => 'Unauthorized',
                402 => 'Payment Required',
                403 => 'Forbidden',
                404 => 'Not Found',
                405 => 'Method Not Allowed',
                406 => 'Not Acceptable',
                407 => 'Proxy Authentication Required',
                408 => 'Request Timeout',
                409 => 'Conflict',
                410 => 'Gone',
                411 => 'Length Required',
                412 => 'Precondition Failed',
                413 => 'Request Entity Too Large',
                414 => 'Request-URI Too Long',
                415 => 'Unsupported Media Type',
                416 => 'Requested Range Not Satisfiable',
                417 => 'Expectation Failed',
                500 => 'Internal Server Error',
                501 => 'Not Implemented',
                502 => 'Bad Gateway',
                503 => 'Service Unavailable',
                504 => 'Gateway Timeout',
                505 => 'HTTP Version Not Supported');

        if( $_status == null ) {
            // return http status array
            return $arr_http_status;
        }

        return ($arr_http_status[$_status]) ? $arr_http_status[$_status] : $status[500];
    }

    function curl_request_data($_target, $_data = "", $_arr_opt = "", $_timeout = 2) {
        $curl_handle = curl_init();
        curl_setopt($curl_handle, CURLOPT_URL, $_target);
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $_timeout);

        if( $_data != "" ) {
            curl_setopt($curlsession, CURLOPT_POST, true);
            curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_data);
        }

        if( $_arr_opt != "" ) {
            if( isset($_arr_opt["auth"]) ) {
                curl_setopt($curl_handle, CURLOPT_HTTPAUTH, $_arr_opt["auth"]);
            }

            if( isset($_arr_opt["username"]) && isset($_arr_opt["password"]) ) {
                curl_setopt($curl_handle, CURLOPT_USERPWD, "{$_arr_opt["username"]}:{$_arr_opt["password"]}");
            }
        }

        $response = curl_exec($curl_handle);
        $http_code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);

        // 1. curl 오류 검출
        if( curl_errno($curl_handle) != 0 ) {
            curl_close($curl_handle);

            return '{
                    "code": 503,
                    "message": "Service Unavailable",
                    "result": ""
            }';
        }
        curl_close($curl_handle);

        // 2. http response code 오류 검출
        if( $http_code != 200 ) {
            return '{
                    "code": ' . $http_code . ',
                    "message": "' . get_http_status_message($http_code) . '",
                    "result": ""
            }';
        }

        // 3. json format 오류 검출
        json_decode($response);
        if( json_last_error() != JSON_ERROR_NONE ) {
            return '{
                    "code": 500,
                    "message": "Internal Server Error",
                    "result": "invalid JSON format"
            }';
        }

        // 4. 정상 case 출력
        return $response;
    }
?>

 

소스코드 : example.php

<?php
    include_once("./func_curl.php");

    /*
        # Make option info
        auth 	 => CURLAUTH_BASIC, CURLAUTH_DIGEST, CURLAUTH_GSSNEGOTIATE, CURLAUTH_NTLM, CURLAUTH_ANY, CURLAUTH_ANYSAFE
        username => "username"
        password => "password"
    */
    $str_target = "<Rest API Server>";  // e.g. http://192.168.1.99/api/status
    $str_data	= "";	                // "" is GET method, other POST method
    $arr_opt	= array("auth" => CURLAUTH_DIGEST, "username" => "root", "password" => "root");

    // curl request
    $response = curl_request_data($str_target, $str_data, $arr_opt);

    print_r(json_decode($response));
?>

 

 

결과 #1, 인증이 필요한 API 서버로 curl 요청을 했을 때, 코드와 결과 

- <Digest auth IP 장치>에는 인증을 필요로 하는 Rest API 서버의 URL을 명세해준다.

<?php
$json_data = json_decode(curl_request_data("<Digest auth IP 장치, 인증 정보 미입력>"));
print_r($json_data);

/*
stdClass Object
(
    [code] => 401
    [message] => Unauthorized
    [result] =>
)
*/
?>

 

결과 #2, 정상적인 API 서버로 curl 요청을 했을 때, 코드와 결과

- <일반 IP 장치>에는 인증을 필요로 하지 않는 Rest API 서버의 URL을 명세해준다.

<?php

$json_data = json_decode(curl_request_data("<일반 IP 장치>"));
print_r($json_data);

/*
stdClass Object
(
    [code] => 200
    [message] => OK
    [result] => stdClass Object
        (
            [Attributes] => stdClass Object
                (
                    [Version] => 1.0
                    [SupportMethod] => GET
                    [SupportAPI] => enable
                    [AccessControl] => guest
                )
            [DeviceType] => default
        )

)
*/
?>

 

그 외 Header 를 통한 인증이나 Data format 을 바꾸는 등의 작업이 필요하다면 위 소스코드의 curl request 함수의 setopt header 를 사용하면 되고,

 

 

 

끝.

 

 

댓글