我正在构建一个基于PHP的网页。我想使用REST API在AZURE Cosmos DB中存储,读取和更新数据。 第一个挑战是使用主密钥生成身份验证令牌。我使用了Microsoft文档:https://docs.microsoft.com/de-de/rest/api/cosmos-db/access-control-on-cosmosdb-resources 和邮递员收藏品*作为构建以下代码的参考。
*请参阅 https://www.youtube.com/watch?v=2ndj_-zp82Y https://github.com/MicrosoftCSA/documentdb-postman-collection
我使用了来自邮递员的控制台日志来比较每个步骤,并发现有不同的结果**,但是我不知道如何像从邮递员一样从我的PHP中获得相同的结果
** key64 PHP: WUtDMFF5VWZkZ1NsTFp5UmU5ZVBMbW9jV3ZSN ..... == key64邮递员: 60a0b443251f7604a52d9c917bd78f2e6a1c5af4790d3f67dc7dbd513d173418 ...否==最后 authstring PHP: 类型%253Dmaster%2526ver%253D1.0%2526sig%..... authstring邮递员: 类型%3Dmaster%26ver%3D1.0%26sig%3 .....
POSTMAN (JS)
// store our master key for documentdb
var mastKey = postman.getEnvironmentVariable("DocumentDBMasterKey");
console.log("mastKey = " + mastKey);
// store our date as RFC1123 format for the request
var today = new Date();
var UTCstring = today.toUTCString();
postman.setEnvironmentVariable("RFC1123time", UTCstring);
// Grab the request url
var url = request.url.trim();
console.log("request url = " + url);
// strip the url of the hostname up and leading slash
var strippedurl = url.replace(new RegExp('^https?://[^/]+/'),'/');
console.log ("stripped Url = " + strippedurl);
// push the parts down into an array so we can determine if the call is on a specific item
// or if it is on a resource (odd would mean a resource, even would mean an item)
var strippedparts = strippedurl.split("/");
var truestrippedcount = (strippedparts.length - 1);
console.log(truestrippedcount);
// define resourceId/Type now so we can assign based on the amount of levels
var resourceId = "";
var resType = "";
// its odd (resource request)
if (truestrippedcount % 2)
{
console.log("odd");
// assign resource type to the last part we found.
resType = strippedparts[truestrippedcount];
console.log("resType");
console.log(resType);
if (truestrippedcount > 1)
{
// now pull out the resource id by searching for the last slash and substringing to it.
var lastPart = strippedurl.lastIndexOf("/");
resourceId = strippedurl.substring(1,lastPart);
console.log(resourceId);
}
}
else // its even (item request on resource)
{
console.log("even");
// assign resource type to the part before the last we found (last is resource id)
resType = strippedparts[truestrippedcount - 1];
console.log("resType");
// finally remove the leading slash which we used to find the resource if it was
// only one level deep.
strippedurl = strippedurl.substring(1);
console.log("strippedurl");
// assign our resourceId
resourceId = strippedurl;
console.log("resourceId");
console.log(resourceId);
}
// assign our verb
var verb = request.method.toLowerCase();
// assign our RFC 1123 date
var date = UTCstring.toLowerCase();
// parse our master key out as base64 encoding
var key = CryptoJS.enc.Base64.parse(mastKey);
console.log("key = " + key);
// build up the request text for the signature so can sign it along with the key
var text = (verb || "").toLowerCase() + "\n" +
(resType || "").toLowerCase() + "\n" +
(resourceId || "") + "\n" +
(date || "").toLowerCase() + "\n" +
"" + "\n";
console.log("text = " + text);
// create the signature from build up request text
var signature = CryptoJS.HmacSHA256(text, key);
console.log("sig = " + signature);
// back to base 64 bits
var base64Bits = CryptoJS.enc.Base64.stringify(signature);
console.log("base64bits = " + base64Bits);
// format our authentication token and URI encode it.
var MasterToken = "master";
var TokenVersion = "1.0";
auth = encodeURIComponent("type=" + MasterToken + "&ver=" + TokenVersion + "&sig=" + base64Bits);
console.log("auth = " + auth);
// set our auth token enviornmental variable.
postman.setEnvironmentVariable("authToken", auth);
PHP代码
#PHP Script
function generateAuthKey($url, $method){
$key = "****************";
$date = new DateTime('');
$date = $date->format('D, d M Y H:i:s O');
$ressourcetype = "";
$strippedurl = parse_url($url, PHP_URL_PATH);
$strippedparts = explode("/", $strippedurl);
$strippedurlcount = sizeof($strippedparts)-1;
#GET RESSOURCE TYPE
if ($strippedurlcount % 2){
$resType = $strippedparts[$strippedurlcount];
if ($strippedurlcount > 1){
$ressourcetype = $strippedparts[$strippedurlcount];
}
}
else{
$ressourcetype = $strippedparts[$strippedurlcount-1];
}
$sig = nl2br(strtolower($method)."\n".strtolower($ressourcetype)."\n".$strippedurl."\n".strtolower($date)."\n".""."\n");
$sig = utf8_encode($sig);
$key64 = base64_encode($key);
echo $key64."\n";
$hmac = hash_hmac('sha256',$sig,$key64);
$token = "type=master&ver=1.0&sig=".$hmac;
return urlencode($token);
}
如何更改PHP脚本以提供与Postman(JS)相同的输出?
答案 0 :(得分:0)
我认为问题在于以下代码行:
$key64 = base64_encode($key);
根据REST API documentation
,您应该对密钥进行base64_decode
,因为该密钥已经通过base64编码。
请尝试将您的代码更改为:
$key64 = base64_decode($key);