Я проверял код и сделал следующее:
- Очистить все куки
- Запустить пустой запрос на вход
- Захватить фокса 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;
}
Надеюсь, это может быть полезно.