首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有Emulator的Cosmos DB REST API (目前)

带有Emulator的Cosmos DB REST API (目前)
EN

Stack Overflow用户
提问于 2018-01-05 13:04:33
回答 2查看 532关注 0票数 0

我正在尝试使用Cosmos DB RestAPI列出我的本地(模拟器)实例上的数据库,但没有走得太远。有没有人知道我做错了什么。

代码语言:javascript
复制
var crypto = require("crypto");  
var request = require('request');

function getAuthorizationTokenUsingMasterKey(verb, resourceType, resourceId, date, masterKey) {  
    var key = new Buffer(masterKey, "base64");  

    var text = (verb || "").toLowerCase() + "\n" +   
           (resourceType || "").toLowerCase() + "\n" +   
           (resourceId || "") + "\n" +   
           date.toLowerCase() + "\n" +   
           "" + "\n";  

    var body = new Buffer(text, "utf8");  
    var signature = crypto.createHmac("sha256", key).update(body).digest("base64");  

    var MasterToken = "master";  

    var TokenVersion = "1.0";  

    return encodeURIComponent("type=" + MasterToken + "&ver=" + TokenVersion + "&sig=" + signature);  
}  

function doTest() {

  const key = getAuthorizationTokenUsingMasterKey("get","dbs","", "Fri, 5 Jan 2018 04:31:00 GMT", "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==")
  console.log(key);

  var headers = {}
  headers['content-length'] = body.length;
  headers['authorization'] = key
  headers["x-ms-version"] = "2017-02-22"
  headers["x-ms-date"] = "2018-01-05T04:31:00Z"

  request({method : "get", "url": "https://localhost:8081/dbs", "headers": headers, "body": body}, function (error, response, body) {
    console.log("Error is : " + JSON.stringify(error));
    console.log("Response is " + JSON.stringify(response, null, 2));
    console.log("body is " + JSON.stringify(body))
  });
}
doTest();

当我对Cosmos DB Emulator运行此命令时,会得到以下输出。

代码语言:javascript
复制
G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo>node cosmosTest

type%3Dmaster%26ver%3D1.0%26sig%3DKvaXXxoeUpN6QuKz%2BA1w91EWHSdo0RdBjtI46tDBrgY%3D

代码语言:javascript
复制
Error is : null
Response is {
  "statusCode": 401,
  "body": "{\"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: 'get\\ndbs\\n\\n2018-01-05t04:31:00z\\n\\n'\\r\\nActivityId: 0a00a781-f393-41e5-8ac0-4526af9110cc, Microsoft.Azure.Documents.Common/1.19.102.5\"}",
  "headers": {
    "transfer-encoding": "chunked",
    "content-type": "application/json",
    "content-location": "https://localhost:8081/dbs",
    "server": "Microsoft-HTTPAPI/2.0",
    "x-ms-activity-id": "0a00a781-f393-41e5-8ac0-4526af9110cc",
    "x-ms-gatewayversion": "version=1.19.102.5",
    "date": "Fri, 05 Jan 2018 04:31:37 GMT",
    "connection": "close"
  },
  "request": {
    "uri": {
      "protocol": "https:",
      "slashes": true,
      "auth": null,
      "host": "localhost:8081",
      "port": "8081",
      "hostname": "localhost",
      "hash": null,
      "search": null,
      "query": null,
      "pathname": "/dbs",
      "path": "/dbs",
      "href": "https://localhost:8081/dbs"
    },
    "method": "get",
    "headers": {
      "content-length": 0,
      "authorization": "type%3Dmaster%26ver%3D1.0%26sig%3DKvaXXxoeUpN6QuKz%2BA1w91EWHSdo0RdBjtI46tDBrgY%3D",
      "x-ms-version": "2017-02-22",
      "x-ms-date": "2018-01-05T04:31:00Z"
    }
  }
}
body is "{\"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: 'get\\ndbs\\n\\n2018-01-05t04:31:00z\\n\\n'\\r\\nActivityId: 0a00a781-f393-41e5-8ac0-4526af9110cc, Microsoft.Azure.Documents.Common/1.19.102.5\"}"
EN

回答 2

Stack Overflow用户

发布于 2018-01-05 15:48:10

我不太熟悉Node.js代码,所以我尝试通过REST API使用下面的java代码访问Azure Cosmos Emulator,如下所示,.It对我来说工作得很好。

代码语言:javascript
复制
import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class ListDataBaseRest {
    private static final String key = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";

    public static void main(String args[]) throws Exception {

        String urlString = "https://localhost:8081/dbs";
        HttpURLConnection connection = (HttpURLConnection) (new URL(urlString)).openConnection();
        getFileRequest(connection, key);
        connection.connect();


        System.out.println("Response message : " + connection.getResponseMessage());
        System.out.println("Response code : " + connection.getResponseCode());

        BufferedReader br = null;
        if (connection.getResponseCode() != 200) {
            br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
        } else {
            br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
        }
        System.out.println("Response body : " + br.readLine());
    }

    public static void getFileRequest(HttpURLConnection request, String key)
            throws Exception {
        SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
        fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
        String stringToSign = "GET".toLowerCase() + "\n"
                + "dbs".toLowerCase() + "\n"
                + "" + "\n"
                + date.toLowerCase() + "\n"
                + "" + "\n";
        System.out.println("stringToSign : " + stringToSign);
        String auth = getAuthenticationString(stringToSign);

        request.setRequestMethod("GET");
        request.setRequestProperty("x-ms-date", date);
        request.setRequestProperty("x-ms-version", "2017-02-22");
        request.setRequestProperty("Authorization", auth);
        request.setRequestProperty("Content-Type", "application/query+json");

    }

    private static String getAuthenticationString(String stringToSign) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
        String authKey = new String(Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8"))));
        System.out.println("authkey:" + authKey);
        String auth = "type=master&ver=1.0&sig=" + authKey;
        auth = URLEncoder.encode(auth);
        System.out.println("authString:" + auth);
        return auth;
    }

}

输出结果:

错误代码401

输入授权令牌无法为请求提供服务。请检查预期负载是否按照协议构建,并检查正在使用的密钥。

根据我的经验,上面的错误与Authorization header生成有关。我试着找出out代码之间的区别。我注意到您的date参数是静态的,而不是获取当前时间。

另外,x-ms-date头的格式不符合标准,需要像Tue, 01 Nov 1994 08:12:31 GMT一样。

有任何问题,请让我知道。

票数 2
EN

Stack Overflow用户

发布于 2018-01-06 08:26:11

Masterkey签名生成应使用RFC 7231格式。下面是

signature specification reference

对于节点,下面的代码参考可能会有所帮助

Signature generation

Usage

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48107451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档