GWN - HTTP API Signature Computation Issue - PHP Curl


#1

Hi,

I am getting an Authentication Failure message with code retCode:50003 when trying to consume the GWN APIs.

I am successfully getting the access token, however, when trying to compute the signature - the exact way as the doc here - and call any API I got the above error message.

Here how I computed the signature and call the API.

         $timestamp = round(microtime(true) * 1000);

            $public_params = array('access_token' => $this->token,
                'appID' => $this->client_id,
                'secretKey' => $this->client_secret,
                'timestamp' => $timestamp);

            $public_params['signature'] = hash('sha256', '&' . http_build_query($public_params) . '&');
            
            unset($public_params['secretKey']);

            $ch = curl_init();
            $options = array(
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_URL => $this->base_url_api . '/network/list?' . http_build_query($public_params),
                CURLOPT_HTTPHEADER => array(
                    "Content-type: application/json"
                )
            );
            curl_setopt_array($ch, $options);
            $response = curl_exec($ch);

#2

Hi omer,

I am working through the Signature Computation also - did you have any update or find a solution to the Issue you experienced here?

I am being thrown a 401 error code.

Thanks.


#3

The docs state to generate the signature using the body and only do so if the request has a body.


#4

Hi Jboden555,

Yes, it got to work by adding a payload to the request as below.

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

Remember the payload body should include the secret key parameter and you should remove it from the request parameters,

Hope this helps.


#5

thank you-

What if there is no body to add in the request?


#6

I missed this before, but the signature for a request with a body:

signature=sha256 (&params&sha256(body)&)

Signature of a request without a body:

signature=sha256 (&params&)


#7

Great, working now I added the body request. Thanks all.


#8

I have been able to call network/list and network/detail but receiving Authentication Failure when calling network/create. Payload is as follows;

$body_data = array(
            'networkName'           => "A_55_B",
            'country'               => "US",
            'timezone'              => "America/New_York",
            'networkAdministrators' => [
                00000,
                00000
            ],
            'cloneNetworkId'        => 12345
        );

Not sure if it is because of the type for networkAdministrators or cloneNetworkId but the edits I tried for that still returned the error.


#9

I found an answer that worked - I added JSON_UNESCAPED_SLASHES when encoding the data.

$body = json_encode($body_data, JSON_UNESCAPED_SLASHES);

Also unquoted the networkAdministrators array values and the call was successful.


#10

any chance you could post your updated complete code? ta.


#11

Hello Mr. Boden!

Can you please share the piece of code to query clients list? I cant perform any POST… Just GET.

Do I have to put the body params in the signature first calculation? It’s kinda confusing to me. I’m using Python. But I can read PHP.

Here’s what my code looks like:

def networkDetail():

    endpoint = base_url + "/oapi/v1.0.0/network/detail?"

    params = {
        "access_token": get_api_key(),
        "appID": client_id,
        "secretKey": client_secret,
        "timestamp": int(time.time())*1000
    }

    encoded_params = urllib.parse.urlencode(params)

    json_body = {"id":63312}

    json_string = json.dumps(json_body)

    json_sha256 = sha256(json_string)

    params["signature"] = sha256(f"&{encoded_params}&{json_sha256}&")

    del(params["secretKey"])

    headers = {"Content-type": "application/json"}

    url = endpoint + urllib.parse.urlencode(params)

    response = requests.post(url, headers=headers, data=json_body)

    if response.status_code == 200:
        print("Response:", response.json())
    else:
        print("Request failed with status code:", response.status_code)

#12

Sorry for the delay - I have a config file that contains $clientId, $clientSecret and $resource, here is what I have:

########################### Create Network ############################## 
echo "<h3>Create Network Call:<h3>";

############## get access token ###############

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.gwn.cloud/oauth/token");
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'resource' => $resource,
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'client_credentials'
));

$data = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);

$data_obj = json_decode($data);
$access_token = $data_obj->{"access_token"};

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo "Access Token Success";
// echo "Access Token: " . $access_token;
}

// Add Signature Computation code
        $timestamp = round(microtime(true) * 1000);

        $public_params = [
            'access_token' => $access_token,
            'appID'        => $clientId,
            'secretKey'    => $clientSecret,
            'timestamp'    => $timestamp
        ];

    //use below test code for network/create call using MASTER TEMPLATE NETWORK ID 00000
    // Create Network
    $body_data = [
            'networkName'           => "networkName",
            'country'               => 'US',
            'timezone'              => 'America/New_York',
            'networkAdministrators' => [
                11111,     
                22222
            ],
            'cloneNetworkId'        => 00000
    ];
    $params = http_build_query($public_params);
    $body = json_encode($body_data, JSON_UNESCAPED_SLASHES);

    $body_signature  = hash("sha256",$body);
    $signature = hash("sha256","&".$params."&".$body_signature."&");

    echo "<br><br>".$body;

    $payload_data = [
    'access_token' => $access_token,
    'appID'        => $clientId,
    'timestamp'    => $timestamp,
    'signature'    => $signature
    ];

    $payload = http_build_query($payload_data);
    $ch = curl_init();
    curl_setopt_array($ch, [
    CURLOPT_URL => 'https://www.gwn.cloud/oapi/v1.0.0/network/create'."?".$payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HTTPHEADER => [
    "Content-type: application/json"
    ]
    ]);

    $response_create_net = curl_exec($ch);
    $err = curl_error($ch);

    curl_close($ch);

    if ($err) {
        echo "cURL Error #:" . $err;
    }else {
        echo "<br><br>";
        $response_create_net = json_decode($response_create_net);
        echo "<pre>";
        print_r($response_create_net);
        echo "</pre>";
        // return $response;
        };

#13

Hi gabemocan, see my last post - that should help.