卷曲以使用摘要标志获取

curl to fetch with digest flag

关于这个主题还有其他问题,但似乎对我没有任何帮助。
我有一个功能性的 CURL,但我想转换为 JS(使用 Node)。

CURL

curl --user "uername:pass" --digest \
 --header "Content-Type: application/json" \
 --include \
 --request POST "https://cloud.mongodb.com/api/atlas/v1.0/groups/MY_GROUP/clusters/MY_CLUSTER/fts/indexes?pretty=true" \
 --data '{
     "collectionName": "collname",
     "database": "myDB",
     "mappings": {
       "dynamic": true
     },
     "name": "default"
   }'

回应

HTTP/2 401 www-authenticate: Digest realm="MMS Public API", domain="", nonce="OtwBmcu89QuyVMLW6FP1W/ZjD3preQl0", algorithm=MD5, qop="auth", stale=false content-type: application/json content-length: 106 x-envoy-upstream-service-time: 2 date: Wed, 16 Feb 2022 17:05:37 GMT server: envoy

HTTP/2 200 date: Wed, 16 Feb 2022 17:05:37 GMT strict-transport-security: max-age=31536000; includeSubdomains; referrer-policy: strict-origin-when-cross-origin x-permitted-cross-domain-policies: none x-content-type-options: nosniff x-mongodb-service-version: gitHash=8284a4ea05955cb13c38df5489a3794b9a691d4f; versionString=v20220216 content-type: application/json x-frame-options: DENY content-length: 216 x-envoy-upstream-service-time: 154 server: envoy

我不确定为什么会有 401 和 200,但它确实有效。但是我得到了一个没有 --digest 标志的 401,下面的解决方案 none 似乎包含摘要?

以下是我尝试过的所有方法,都是return 401“您无权使用此资源。”:

获取

fetch(url,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization:
        'Basic ' +
        Buffer.from(
          'user:pass'
        ).toString('base64'),
    },
    body: dataString,
  }
)

相同的结果

要求

const headers = {
  'Content-Type': 'application/json',
};

var options = {
  url: url,
  method: 'POST',
  headers: headers,
  body: dataString,
  auth: {
    user: 'user',
    pass: 'pass',
  },
};

request(options, (error: any, response: any, body: any) => {
    ...
});

node-libcurl

  const curl = new Curl();
  curl.setOpt(Curl.option.HTTPHEADER, [
    'Content-Type: application/json',
  ]);
  curl.setOpt(Curl.option.URL, url);
  curl.setOpt(Curl.option.POST, true);
  curl.setOpt(Curl.option.USERPWD, 'user:pass');
  curl.setOpt(Curl.option.POSTFIELDS, dataString);

甚至

PHP

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "...");
curl_setopt($ch, CURLOPT_USERPWD, 'user:pass');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$result = curl_exec($ch);
curl_close($ch);

编辑包 request-digest

digestRequest
  .requestAsync({
    host: url,
    path: urlPath,
    port: 80,
    method: 'POST',
    json: true,
    headers: {
      'Content-Type': 'application/json',
    },
    body: body,
  })
  .then(function (response: any) {
    console.log(response);
  })
  .catch(function (error: any) {
    console.log(error);
  });

回应

Error: Bad request, answer is empty

PHP

您需要指定它是摘要:

curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

节点获取

这是我找到的 here:

fetch(url, {
    ... 
    headers: {
        'Authorization': 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64')
    }
    ...
})

将您的代码与上面建议的代码进行比较,我发现您的代码中缺少 , 'binary'

request-digest

有一个 request-digest 包可以帮助您。示例(取自本段分享的link):

回调

var digestRequest = require('request-digest')('username', 'password');
digestRequest.request({
  host: 'http://test.com',
  path: '/api/v1/test.json',
  port: 80,
  method: 'GET',
  headers: {
    'Custom-Header': 'OneValue',
    'Other-Custom-Header': 'OtherValue'
  }
}, function (error, response, body) {
  if (error) {
    throw error;
  }
 
  console.log(body);
});

Promise-only

var digestRequest = require('request-digest')('username', 'password');
digestRequest.requestAsync({
  host: 'http://test.com',
  path: '/api/v1/test.json',
  port: 80,
  method: 'GET',
  excludePort: false,
  headers: {
    'Custom-Header': 'OneValue',
    'Other-Custom-Header': 'OtherValue'
  }
})
.then(function (response) {
  console.log(response.body);
})
.catch(function (error) {
  console.log(error.statusCode);
  console.log(error.body);
});