Souvik Ghosh
Souvik Ghosh

Reputation: 4606

Using REST for CRUD operations in Azure Cosmos DB

I am trying do CRUD operations on Azure Cosmos DB using REST. As per the link- https://learn.microsoft.com/en-us/rest/api/documentdb/create-a-document I have created my payload and trying to test it using Restman in Opera browser. Below is my payload details-

Headers

Authorization       ***************************

Content-Type        application/query+json

x-ms-date           Tue, 05 Dec 2017 16:49:31 GMT

x-ms-session-token  Session

x-ms-version        2017-02-22

Body

id        sg4c828f-31f8-4db4-8e7c-e8bdff222dsg

value     {     "id": "AndersenFamily",     "LastName": "Andersen",     "Parents": [       {         "FamilyName": null,         "FirstName": "Thomas"       },       {         "FamilyName": null,         "FirstName": "Mary Kay"       }     ],     "Children": [       {         "FamilyName": null,         "FirstName": "Henriette Thaulow",         "Gender": "female",         "Grade": 5,         "Pets": [           {             "GivenName": "Fluffy"           }         ]       }     ],     "Address": {       "State": "WA",       "County": "King",       "City": "Seattle"     },     "IsRegistered": true   }

The auth-token which is put in the request header has been generated in C# using below code (as per the sample in the link mentioned above)-

string GenerateAuthToken(string verb, string resourceType, string resourceId, string date, string key, string keyType, string tokenVersion)
{
    var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };

    verb = verb ?? "";
    resourceType = resourceType ?? "";
    resourceId = resourceId ?? "";

    string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
            verb.ToLowerInvariant(),
            resourceType.ToLowerInvariant(),
            resourceId,
            date.ToLowerInvariant(),
            ""
    );

    byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
    string signature = Convert.ToBase64String(hashPayLoad);

    return System.Web.HttpUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
        keyType,
        tokenVersion,
        signature));
}

This is how pass the parameters-

GenerateAuthToken("GET", "dbs", "dbs/ToDoList", "Tue, 05 Dec 2017 16:49:31 GMT", PARENT_KEY, "master", "1.0");

So when I make the POST request to the URL-

https://<account_name>.documents.azure.com:<port>/dbs/DCEAAA==/colls/DCEAAIcEVAA=/docs

I get below response-

{ "code": "Unauthorized", "message": "The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'post\ndocs\ndceaaicevaa=\ntue, 05 dec 2017 16:49:31 gmt\n\n'\r\nActivityId: 7565996c-d008-438d-a1e9-744d4871948a, Microsoft.Azure.Documents.Common/1.19.121.4" }

I am clueless what exactly is going wrong here. Please let me know if someone have any ideas. For any clarifications please let me know.

Edit: Adding the Restman screenshot below- enter image description here

Upvotes: 0

Views: 2380

Answers (1)

Tom Sun
Tom Sun

Reputation: 24539

I follow up you mentioned Document Create Document API, and do a demo to create documentdb document with rest API. You could refer to it. For other operates you could follow the following code and construct the hashed token.

According to the Common Azure Cosmos DB REST request headers, if we want to create a document we need to prepare the Header as following

Authorization,x-ms-date,Content-Type,x-ms-version

We could get the x-m-version from this document. The latest version is 2017-02-22.

We could get the demo code you mentioned from this document,about how to constructing the hashed token signature for a master token please refer to this document. From the document we could know that resourceType could be "dbs", "colls", "docs". We need to create a document, so resourceType = docs

var databaseId = "databaseName";
var collectionId = "collectionName";
var datetime = DateTime.UtcNow.ToString("R");
var verb = "post";
var resourceType = "docs"; //
var resourceId = $"dbs/{databaseId}/colls/{collectionId}";
var mastKey = "mastkey value";
var keyType = "master";
var tokenVersion = "1.0";
var authToken = GenerateAuthToken(verb, resourceType, resourceId, datetime, mastKey, keyType, tokenVersion);

We also need to get the x-ms-date value from the above mentioned code varible datetime

enter image description here

Post https://{documentDBAccount}.documents.azure.com:443/dbs/{databaseName}/colls/{collectionId}/docs 

enter image description here

Update:

Please use the following data as json body

{
    "id": "sg4c828f-31f8-4db4-8e7c-e8bdff222dsg",
    "value": {
        "id": "AndersenFamily",
        "LastName": "Andersen",
        "Parents": [
            {
                "FamilyName": null,
                "FirstName": "Thomas"
            },
            {
                "FamilyName": null,
                "FirstName": "Mary Kay"
            }
        ],
        "Children": [
            {
                "FamilyName": null,
                "FirstName": "Henriette Thaulow",
                "Gender": "female",
                "Grade": 5,
                "Pets": [
                    {
                        "GivenName": "Fluffy"
                    }
                ]
            }
        ],
        "Address": {
            "State": "WA",
            "County": "King",
            "City": "Seattle"
        },
        "IsRegistered": true
    }
}

enter image description here

Upvotes: 2

Related Questions