我正在尝试将Cookie添加到我的请求中:
在这里,我收到csrftoken
的{{1}}请求:
GET
在这里,我尝试使用Dio软件包执行 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
我得到403状态代码,因为我需要添加为Cookie 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);
}
。
我应该如何进行?
答案 0 :(得分:2)
Cookie Manager
您可以使用cookieJar管理请求/响应cookie。
dio cookie管理API基于撤回的cookie_jar。
您可以创建一个CookieJar或PersistCookieJar来自动管理cookie,并且默认情况下dio使用CookieJar,这会将cookie保存在RAM中。如果要保留cookie,可以使用PersistCookieJar类,示例代码如下:
var dio = new Dio();
dio.cookieJar=new PersistCookieJar("./cookies");
PersistCookieJar是一个cookie管理器,它实现RFC中声明的标准cookie策略。 PersistCookieJar将cookie保留在文件中,因此,如果应用程序退出,则cookie始终存在,除非显式调用delete。
有关cookie_jar的更多详细信息,请参见:https://github.com/flutterchina/cookie_jar。
答案 1 :(得分:0)
检查csrftoken是否需要在标头和cookie中传递,或者仅在其中之一中传递。有时需要将其作为标头包括在内,如下面的示例所示,但是标头名称有所不同。要保留cookie,请使用PersistCookieJar。其他选项通过BaseOptions(以前称为Options)保留。
将这些插件的latest versions添加到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;
}
}
}