Отправить запрос с Cookies в Flutter - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь добавить файлы cookie в мой запрос:

Здесь я получаю csrftoken с запросом GET:

 Future<String> getCsrftoken() async{
       var response = await http.get(Uri.encodeFull('http://test/accounts/login/'));
       var csrftoken = response.headers.remove('set-cookie').substring(10,74); //csrf 
       64 chars
       return csrftoken;
    }

Здесь я пытаюсь выполнитьPOST (application/x-www-form-urlencoded) запрос с использованием пакета Дио .

getSessionId() async {
  var csrf = await getCsrftoken();
  var cj = new CookieJar();
  List<Cookie> cookies = [new Cookie("csrftoken", csrf)];
  cj.saveFromResponse(Uri.parse("http://test/accounts/login/"), cookies);
  List<Cookie> results = cj.loadForRequest(Uri.parse("http://test/accounts/login/"));
  var dio = new Dio(new Options(
      baseUrl: "http://test/accounts/login/",
      connectTimeout: 5000,
      receiveTimeout: 100000,
      // 5s
      headers: {
      },
      contentType: ContentType.JSON,
      // Transform the response data to a String encoded with UTF8.
      // The default value is [ResponseType.JSON].
      responseType: ResponseType.PLAIN
  ));

  Response<String> response;

  response = await dio.post("",
    data: {
      "username": "username",
      "password": "password",
      "csrfmiddlewaretoken" : getCsrftoken()
    },
    // Send data with "application/x-www-form-urlencoded" format
    options: new Options(
        contentType: ContentType.parse("application/x-www-form-urlencoded")),
  );
  print(response.statusCode);
}

Я получаю код состояния 403, потому что мне нужно добавить в качестве cookie csrftoken.

Как мне поступить?

Ответы [ 2 ]

0 голосов
/ 01 июня 2019

Проверьте, нужно ли передавать csrftoken в заголовок и cookie или только в один из них.Иногда его нужно включать в качестве заголовка, что показано в приведенном ниже примере, но имя заголовка меняется.Чтобы сохранить куки, используйте PersistCookieJar.Другие параметры сохраняются через BaseOptions (ранее назывался Options).

Добавить в pubspec.yaml последние версии этих плагинов

  path_provider: ^1.1.0
  dio: ^2.1.6
  cookie_jar: ^1.0.0

В новом классе с именем webFunctions:

import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';

class webFunctions {
  final Dio _dio = Dio();
  PersistCookieJar persistentCookies;
  final String URL = "http://test/";

  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }

  Future<Directory> get _localCoookieDirectory async {
    final path = await _localPath;
    final Directory dir = new Directory('$path/cookies');
    await dir.create();
    return dir;
  }

  Future<String> getCsrftoken() async{
    try {
      String csrfTokenValue;
      final Directory dir = await _localCoookieDirectory;
      final cookiePath = dir.path;
      persistentCookies = new PersistCookieJar(dir: '$cookiePath');
      persistentCookies.deleteAll(); //clearing any existing cookies for a fresh start
      _dio.interceptors.add(
          CookieManager(persistentCookies) //this sets up _dio to persist cookies throughout subsequent requests
      );
      _dio.options = new BaseOptions(
        baseUrl: URL,
        contentType: ContentType.json,
        responseType: ResponseType.plain,
        connectTimeout: 5000,
        receiveTimeout: 100000,
        headers: {
          HttpHeaders.userAgentHeader: "dio",
          "Connection": "keep-alive",
        },
      ); //BaseOptions will be persisted throughout subsequent requests made with _dio
      _dio.interceptors.add(
          InterceptorsWrapper(
              onResponse:(Response response) {
                List<Cookie> cookies = persistentCookies.loadForRequest(Uri.parse(URL));
                csrfTokenValue = cookies.firstWhere((c) => c.name == 'csrftoken', orElse: () => null)?.value;
                if (csrfTokenValue != null) {
                  _dio.options.headers['X-CSRF-TOKEN'] = csrfTokenValue; //setting the csrftoken from the response in the headers
                }
                return response;
              }
          )
      );
      await _dio.get("/accounts/login/");
      return csrfTokenValue;
    } catch (error, stacktrace) {
      print("Exception occured: $error stackTrace: $stacktrace");
      return null;
    }
  }

  getSessionId() async {
    try {
      final csrf = await getCsrftoken();
      FormData formData = new FormData.from({
        "username": "username",
        "password": 'A *passphrase* is stronger than a password.',
        "csrfmiddlewaretoken" : '$csrf'
      });
      Options optionData = new Options(
        contentType: ContentType.parse("application/x-www-form-urlencoded"),
      );
      Response response = await _dio.post("/accounts/login/", data: formData, options: optionData);
      print(response.statusCode);
    } on DioError catch(e) {
      if(e.response != null) {
        print( e.response.statusCode.toString() + " " + e.response.statusMessage);
        print(e.response.data);
        print(e.response.headers);
        print(e.response.request);
      } else{
        print(e.request);
        print(e.message);
      }
    }
    catch (error, stacktrace) {
      print("Exception occured: $error stackTrace: $stacktrace");
      return null;
    }
  }
}
0 голосов
/ 25 сентября 2018

Из документов Dio Dart API :

Cookie Manager

Вы можете управлять файлами cookie запросов / ответов с помощью cookieJar.

API управления cookie cookie основан на извлеченном cookie_jar.

Вы можете создать CookieJar или PersistCookieJar для автоматического управления файлами cookie, и по умолчанию DIO использует CookieJar, который сохраняет файлы cookie в оперативной памяти.Если вы хотите сохранить файлы cookie, вы можете использовать класс PersistCookieJar, пример кода выглядит следующим образом:

var dio = new Dio();
dio.cookieJar=new PersistCookieJar("./cookies");

PersistCookieJar - менеджер файлов cookie, который реализует стандартную политику файлов cookie, объявленную в RFC.PersistCookieJar сохраняет файлы cookie в файлах, поэтому при выходе из приложения файлы cookie всегда существуют, если только вызов явно не удален.

Подробнее о cookie_jar см. https://github.com/flutterchina/cookie_jar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...