HTTP - это протокол без сохранения состояния, поэтому серверам необходимо каким-то образом идентифицировать клиентов по второму, третьему и последующим запросам, которые они отправляют на сервер. В вашем случае вы можете аутентифицироваться с использованием первого запроса, поэтому вы хотите, чтобы сервер запомнил вас при последующих запросах, чтобы он знал, что вы уже аутентифицированы. Обычный способ сделать это - куки .
Igniter отправляет куки с идентификатором сессии. Вы должны собрать это из каждого ответа и отправить его обратно в следующем запросе. (Серверы иногда меняют идентификатор сеанса (чтобы уменьшить количество таких вещей, как перехваты кликов, которые нам пока не нужно учитывать), поэтому вам нужно продолжать извлекать cookie из каждого ответа.)
Файл cookie приходит в виде заголовка ответа HTTP с именем set-cookie
(их может быть несколько, но, надеюсь, не для простоты). Чтобы отправить cookie обратно, вы добавляете заголовок HTTP-запроса к вашим последующим запросам под названием cookie
, копируя часть информации, извлеченной из заголовка set-cookie
.
Надеемся, что Igniter отправляет только один заголовок set-cookie
, но для целей отладки может оказаться полезным распечатать их все, используя response.headers.forEach((a, b) => print('$a: $b'));
. Вы должны найти Set-Cookie: somename=abcdef; optional stuff
. Нам нужно извлечь строку до, но исключая ;
, т.е. somename=abcdef
В следующих и последующих запросах добавьте заголовок запроса к следующему запросу {'Cookie': 'somename=abcdef'}
, изменив команду post
на:
http.post(url, body: data, headers:{'Cookie': cookie})
Кстати, я думаю, что в приведенном выше коде есть несоответствие awaits
и then
s. Как правило, вы не хотите статики в классах, если они должны быть функциями верхнего уровня. Вместо этого вы можете создать класс с поддержкой cookie, например:
class Session {
Map<String, String> headers = {};
Future<Map> get(String url) async {
http.Response response = await http.get(url, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
Future<Map> post(String url, dynamic data) async {
http.Response response = await http.post(url, body: data, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
void updateCookie(http.Response response) {
String rawCookie = response.headers['set-cookie'];
if (rawCookie != null) {
int index = rawCookie.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie : rawCookie.substring(0, index);
}
}
}