# Authentication

## 1. Signing an API Request

To ensure the security and integrity of your API requests, you need to sign your requests using [<mark style="color:blue;">HMAC SHA256</mark>](https://en.wikipedia.org/wiki/HMAC).&#x20;

This process involves creating a specific string from your request, and then generating a signature using your secret key.

{% hint style="warning" %}
**Requirement:** Request an API Key and Secret Key from Tyga Support at <support@tygapay.com> to access APIs.
{% endhint %}

## 2. Step-by-Step Guide

This guide provides a clear process for signing an API request, from converting a JSON body to a query string (handling nested fields with a dot `.`), constructing the string to sign, and finally signing it using <mark style="color:blue;">HMAC SHA256</mark>.&#x20;

This ensures your API requests are secure and authenticated.

### 2.1 **Create the Query String from JSON**

Depending on your programming language, use the following methods to convert a JSON object to a query string. Note that nested fields are handled using a dot (`.`).

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const qs = require('qs');

const jsonObj = {
    field1: "value2",
    nestedField: {
        nestedField1: "nestedValue1"
    }
};

const queryString = qs.stringify(jsonObj, { encode: false, delimiter: '&', allowDots: true });
console.log(queryString); // Output: field1=value2&nestedField.nestedField1=nestedValue1
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Web;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        var jsonObj = new Dictionary<string, object>
        {
            { "field1", "value2" },
            { "nestedField", new Dictionary<string, object> { { "nestedField1", "nestedValue1" } } }
        };

        var flatDict = FlattenObject(jsonObj);
        var query = HttpUtility.ParseQueryString(string.Empty);

        foreach (var kvp in flatDict)
        {
            query[kvp.Key] = kvp.Value.ToString();
        }

        string queryString = query.ToString().Replace("&amp;", "&");
        Console.WriteLine(queryString); // Output: field1=value2&nestedField.nestedField1=nestedValue1
    }

    public static Dictionary<string, object> FlattenObject(Dictionary<string, object> obj, string parentKey = "", string sep = ".")
    {
        var items = new Dictionary<string, object>();
        foreach (var kvp in obj)
        {
            var newKey = string.IsNullOrEmpty(parentKey) ? kvp.Key : $"{parentKey}{sep}{kvp.Key}";

            if (kvp.Value is Dictionary<string, object> nestedDict)
            {
                var nestedItems = FlattenObject(nestedDict, newKey, sep);
                foreach (var nestedKvp in nestedItems)
                {
                    items[nestedKvp.Key] = nestedKvp.Value;
                }
            }
            else
            {
                items[newKey] = kvp.Value;
            }
        }
        return items;
    }
}
```

{% endtab %}

{% tab title="PHP" %}

```php
$jsonObj = [
    "field1" => "value2",
    "nestedField" => [
        "nestedField1" => "nestedValue1"
    ]
];

function flattenArray($arr, $parentKey = '', $sep = '.') {
    $items = [];
    foreach ($arr as $key => $value) {
        $newKey = $parentKey ? $parentKey . $sep . $key : $key;
        if (is_array($value)) {
            $items = array_merge($items, flattenArray($value, $newKey, $sep));
        } else {
            $items[$newKey] = $value;
        }
    }
    return $items;
}

$flatArr = flattenArray($jsonObj);
$queryString = urldecode(http_build_query($flatArr));
echo $queryString; // Output: field1=value2&nestedField.nestedField1=nestedValue1
```

{% endtab %}
{% endtabs %}

### 2.2 **Construct the String to Sign**

|                                                           |                                                      |
| --------------------------------------------------------- | ---------------------------------------------------- |
| FULL URL:                                                 | <https://api.com/users?test=xxx>                     |
| <mark style="color:green;">API PATH:</mark>               | /users?test=xxx                                      |
| <mark style="color:yellow;">QUERYSTRING FROM BODY:</mark> | field1=value2\&nestedField.nestedField1=nestedValue1 |

{% hint style="success" %}
Construct the string to sign by concatenating the <mark style="color:green;">API PATH</mark> and the <mark style="color:yellow;">QUERYSTRING FROM BODY</mark>:

stringToSign = "<mark style="color:green;">/users?test=xxx</mark><mark style="color:yellow;">field1=value2\&nestedField.nestedField1=nestedValue1</mark>"
{% endhint %}

### 2.3 **Sign the String using&#x20;**<mark style="color:blue;">**HMAC SHA256**</mark>

Use your programming language's libraries to sign the string using <mark style="color:blue;">HMAC SHA256</mark>.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const secretKey = 'your-secret-key';
const stringToSign = '/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1';

const signature = crypto.createHmac('sha256', secretKey)
                        .update(stringToSign)
                        .digest('hex');
console.log(signature);
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Text;
using System.Security.Cryptography;

public class Program
{
    public static void Main()
    {
        string secretKey = "your-secret-key";
        string stringToSign = "/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1";

        string signature = SignString(secretKey, stringToSign);
        Console.WriteLine(signature);
    }

    public static string SignString(string key, string data)
    {
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(key);
        byte[] messageBytes = encoding.GetBytes(data);

        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
        }
    }
}
```

{% endtab %}

{% tab title="PHP" %}

```php
$secretKey = 'your-secret-key';
$stringToSign = '/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1';

$signature = hash_hmac('sha256', $stringToSign, $secretKey);
echo $signature;
```

{% endtab %}
{% endtabs %}
