我正在尝试使用Cosmos DB RestAPI列出我的本地(模拟器)实例上的数据库,但没有走得太远。有没有人知道我做错了什么。
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运行此命令时,会得到以下输出。
G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo>node cosmosTesttype%3Dmaster%26ver%3D1.0%26sig%3DKvaXXxoeUpN6QuKz%2BA1w91EWHSdo0RdBjtI46tDBrgY%3D
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\"}"发布于 2018-01-05 15:48:10
我不太熟悉Node.js代码,所以我尝试通过REST API使用下面的java代码访问Azure Cosmos Emulator,如下所示,.It对我来说工作得很好。
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一样。
有任何问题,请让我知道。
发布于 2018-01-06 08:26:11
https://stackoverflow.com/questions/48107451
复制相似问题