Проверка подлинности POST работает в «запросе», но не в «извлечении узла» - PullRequest
4 голосов
/ 17 февраля 2020

Я написал запрос аутентификации, который работает с модулем request , но не может вернуть желаемый 'токен аутентификации' cook ie с модулем node-fetch , который я я пытаюсь двигаться в сторону, так как «запрос» устарел.

Вот рабочий код с использованием 'request'

  var callback1 = function(err, httpResponse, body){
    console.log("Correctly prints all the cookies we want: ");
    console.log(httpResponse.headers["set-cookie"]);
    if (err){console.log("here it is!"); throw err;}
    else {
      //do more with response
    }
  };
 var callback0 = function(err, httpResponse0, body){

    console.log("Check that sent cookies are identical, from request:");
    console.log(httpResponse0.headers["set-cookie"][0].substr(0,httpResponse0.headers["set-cookie"][0].indexOf(";")));
    if (err){throw err;}
    else {
    var options1 = {
      url: urlString1
      ,headers:{
      'Host': hostName
      ,'User-Agent': myUserAgent
      ,'Accept': myAccept 
      ,'Accept-Language':myAcceptLanguage 
      ,'Accept-Encoding': myAcceptEncoding 
      ,'Referer': "https://"+hostName+'/login'
      ,'Cookie': httpResponse0.headers["set-cookie"][0].substr(0,httpResponse0.headers["set-cookie"][0].indexOf(";"))
      ,'Content-Type':  "application/x-www-form-urlencoded"
      ,'Content-Length': Buffer.byteLength(querystring.stringify(postData))
      ,'Connection': "keep-alive"
      ,'Upgrade-Insecure-Requests': "1"
      ,'DNT': "1"
      ,'TE': "Trailers"
      }
      ,form: {email: myEmail, password: myPassword}
    };
    request.post(options1, callback1);
    }
  }
 var options0 = {
    url: urlString0
    ,headers:{
    'Host': hostName
    ,'User-Agent': myUserAgent
    ,'Accept': myAccept 
    ,'Accept-Language':myAcceptLanguage 
    ,'Accept-Encoding': myAcceptEncoding 
    ,'Referer': "https://"+hostName
    ,'Connection': "keep-alive"
    ,'Upgrade-Insecure-Requests': "1"
    }
  };
  request(options0, callback0);

А вот код в node-fetch, который не может правильно вернуть auth_token cook ie:

  const fetchOptions0 = {
      method: 'GET', 
      headers:{
      'Host': hostName
      ,'User-Agent': myUserAgent
      ,'Accept': myAccept 
      ,'Accept-Language':myAcceptLanguage 
      ,'Accept-Encoding': myAcceptEncoding 
      ,'Referer': "https://"+hostName
      ,'Connection': "keep-alive"
      ,'Upgrade-Insecure-Requests': "1"
      }
  }
  fetch(urlString0, fetchOptions0)
  .then(res0 => {
    console.log("Check that sent cookies are identical, from fetch:");
    console.log(res0.headers.raw()['set-cookie'][0].substr(0, res0.headers.raw()['set-cookie'][0].indexOf(";")));
    const FormData = require('form-data');
    const myForm = new FormData();
    myForm.append('email', myEmail);
    myForm.append('password', myPassword);
    var fetchOptions1 = {
      method: 'POST'
      ,headers:{
      'Host': hostName
      ,'User-Agent': myUserAgent
      ,'Accept': myAccept 
      ,'Accept-Language':myAcceptLanguage 
      ,'Accept-Encoding': myAcceptEncoding 
      ,'Referer': "https://"+hostName+'/login'
      ,'Cookie': res0.headers.raw()['set-cookie'][0].substr(0, res0.headers.raw()['set-cookie'][0].indexOf(";"))
      ,'Content-Type':  "application/x-www-form-urlencoded"
      ,'Content-Length': Buffer.byteLength(querystring.stringify(postData))
      ,'Connection': "keep-alive"
      ,'Upgrade-Insecure-Requests': "1"
      ,'DNT': "1"
      ,'TE': "Trailers"
    }
    ,body:myForm
    };
    fetch(urlString1, fetchOptions1)
    .then(res1=> {console.log("Incorrect cookie, missing auth:"); console.log(res1.headers.raw()['set-cookie']);});
    });

Я попытался записать данные формы, используя JSON .stringify, как предложено в этом ответе, но это не помогло.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Чтобы отправить полезную нагрузку application/x-www-form-urlencoded в тело, просто передайте объект URLSearchParams

const params = new URLSearchParams();
params.append("email", myEmail);
params.append("password", myPassword);

fetch(urlString1, {
  headers: {
    // your headers
    // omit content-length and content-type because node-fetch
    // will handle that for you
  },
  body: params
}).then(response => {
  console.log(response.headers.raw());
})

В вашем примере вы используете FormData, что приводит к записи узла-выборки multipart/formdata как заголовок content-type.

Также вы можете проверить код сервера авторизации, чтобы убедиться, что он правильно отправляет заголовки set-cookie.

Протестировано с:

  • node-fetch v2.6.0
  • nodejs v12.14.0
0 голосов
/ 23 февраля 2020

Существует

, форма: {электронная почта: myEmail, пароль: myPassword}

в request версии кода. Это application/x-www-form-urlencoded
См. https://www.npmjs.com/package/request#applicationx - www-form-urlencoded-url-encoded-forms)

Но есть

body: myForm

в fetch версии кода. И это multipart/form-data
См.

  1. первое предложение https://www.npmjs.com/package/form-data
  2. https://www.npmjs.com/package/request#multipartform - data-multipart-form-uploads
  3. https://www.npmjs.com/package/node-fetch#post -with-form-data-detect-multipart

Но все же

'Content-Type': "application / x- www-form-urlencoded"

в fetch версии

Если ваша конечная точка API не принимает multipart/form-data вам, вероятно, следует переключиться с FormData на URLSearchParams.
См. https://www.npmjs.com/package/node-fetch#post -with-form-parameters

...