Отключить перенаправление в запросе на выборку с помощью React native - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь сканировать сеть, используя React Native, у которого нет API.Он написан на PHP.

Для регистрации пользователя необходимо отправить запрос POST.Ответ возвращает cookie с файлом cookie PHPSessid, который я должен записать, чтобы использовать в последующих запросах.

Я хотел бы получить значение cookie, купить ответ POST - 302, и перенаправление выполняется автоматически, поэтому я не вижу cookie.В узле я смог сделать это с помощью redirect:manual, но он не работает в режиме native native.

Файл cookie отправляется автоматически при последующих запросах, покупка Я пытаюсь вручную управлять файлами cookie с помощьюnative-cookie, и я хотел бы знать, возможно ли это.

Знаете ли вы, как остановить перенаправление?

1 Ответ

0 голосов
/ 04 августа 2019

Я проверял код и сделал следующее:

  • Очистить все куки
  • Запустить пустой запрос на вход
  • Захватить фокса PHPSessID
  • Запустить запрос на вход с этим PHPSessID
  • После этого последующие запросы на выборку автоматически будут иметь файл cookie PHPSessID с действительным зарегистрированным пользователем, поэтому мы можем использовать сайт с простыми выборками

Вот некоторый код, но важно то, что вы делаете первый пустой запрос на вход, захватываете PHPSessid и запускаете реальный запрос на вход с этим PHPSessid.

Это будет основная функция:

import Cookie from 'react-native-cookie';
  // I think this is used only to clear the cookies

function login(user, pass){

    // clear all cookies for all domains
    // We need to start withouth authorization token
    Cookie.clear();

    const makeLoginRequest = (sessid) => 
             makeLoginRequestForUserAndPass(user,pass,sessid);

    return makeInitialRequest()
        .then(getSessionIDFromResponse)
        .then(makeLoginRequest)
        .then(checkIfLoggedAndGetSessionID);
}

Первоначальный запрос - это запрос к сценарию входа. Обратите внимание, что я использовал GET, потому что он работал с моим сайтом, возможно, потребуется пустой пост:

function makeInitialRequest() {
    const INIT_PATH = '/index.php?r=site/login';
    const INIT_URL = site + INIT_PATH;
    const request = new Request(INIT_URL, options....);

    return fetch(request);
}

У нас есть идентификатор сеанса в ответе. Я использовал простое регулярное выражение, чтобы извлечь его. Обратите внимание, что мы не вошли в систему; PHP создал сессию, и вот что у нас здесь:

function getSessionIDFromResponse(response) {
    return getPHPSessIdFromCookie(response.headers.get('set-cookie'));
}

function getPHPSessIdFromCookie(header) {
    const regex = /PHPSESSID=(\w*)/;
    const match = regex.exec(header);
    return match ? match[1] : '';
}

Теперь запрос на вход. Обратите внимание, что я не могу остановить перенаправление здесь, но мне не нужно это делать, потому что у нас может быть PHPSessid позже. Перенаправление должно быть установлено вручную в запросе POST:

function makeLoginRequestForUserAndPass(user, pass, sessid) {
    const request = buildLoginRequest(user, pass, sessid);
    return fetch(request);
}

// This is where we build the real login request
function buildLoginRequest(user, pass, sessid) {
    const LOGIN_PATH = '/index.php?r=site/login';
    const LOGIN_URL = site + LOGIN_PATH;

    const fields = [
        {name: 'LoginForm[username]', value: user},
        {name: 'LoginForm[password]', value: pass},
        etc...
    ];
    const data = translateFieldsToURLEncodedData(fields);

    const headers = {
        'Content-type': 'application/x-www-form-urlencoded',
        Cookie: `PHPSESSID=${sessid}`, // HERE is where you put the data
    };

    const options = { method: 'POST',
        headers: headers,
        mode: 'cors',
        cache: 'default',
        agent: proxy,
        body: data,
        redirect: 'manual'  // VERY IMPORTANT: if you don't do it, the cookie is lost
    };

    return new Request(LOGIN_URL, options);
}

// Simple utility function
function translateFieldsToURLEncodedData(fields){
    let pairs = fields.map( (field) => {
        return encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value);
    });
    return pairs.join('&');
}

Это последняя часть. Чтобы убедиться, что я вошел в систему, я проверил, был ли в ответе текст, принадлежащий странице ошибки входа. Я также получил PHPSessid (я думаю, что он изменился после входа в систему, не уверен, что это было год назад), но я не знаю, использовал ли я его, я думаю, что он был автоматически включен в последующие запросы. Я думаю, что эта часть может быть упрощена и улучшена:

function checkIfLoggedAndGetSessionID(response) {
    return (
        checkIfLoggedOK(response)
            .then(() => getSessionIDFromResponse(response))
    );
}

function checkIfLoggedOK(response){
    return getTextFromResponse(response)
        .then(throwErrorIfNotLogedOk);
}

function getTextFromResponse(response) {
    return response.text();
}

function throwErrorIfNotLogedOk(page) {
    if(isErrorPage(page)) throw new Error("Login failed");
}

function isErrorPage(text) {
    const ERROR_MESSAGE = 'Something that appears in login failed page of your site';
    let n = text.search(ERROR_MESSAGE);
    return n !== -1;
}

Надеюсь, это может быть полезно.

...