繁体   English   中英

flutter/dart http.Client() 的非持久连接

[英]Not persistent connection for flutter/dart http.Client()

我有一个正在运行的django-serversession 一起使用 这里给出了一个来自我的views.py 的简单示例,它应该足以重现我的问题:

def test(request):
    print("Session objects(")
    for k,v in request.session.items():
        print(k,v)
    print(")")
    request.session["a"] = "b"

所以这只是打印当前会话中的所有内容,然后在会话中保存一些虚拟数据。 如果我第一次通过浏览器访问它,输出是

Session objects(
)

所以会话是空的,就像预期的那样。 然后刷新站点后,输出为:

Session objects(
a b
)

也正如预期的那样,所以一切似乎都很好。

但现在我想在我的 flutter 应用程序中使用该网站。 为此,我使用 flutter packacke import 'package:http/http.dart' as http如下所示:

var client = http.Client();

String host = ...; // just the ip:port to my host

void my_request() async {
  var response = await client.get(host + "/path/to/test/");
  response = await client.get(host + "/path/to/test/");
}

所以这应该做的一切就是像我之前在浏览器中手动请求我的网站一样两次。 但现在我的服务器只记录两次:

Session objects(
)

所以很明显,客户端有一个不持久的连接,会话没有被保留。 但是根据文档https://pub.dev/packages/http这应该可以工作

如果您向同一服务器发出多个请求,则可以使用客户端保持打开持久连接,而不是发出一次性请求

这是我的 flutter/dart 应用程序的问题还是我的服务器上的问题? 它可能是颤振包中的一个大包吗?

注意:我首先认为这可能是 csrf 身份验证的问题,因此在我的服务器上将其停用,但这并没有改变任何东西......

您不需要第 3 方库。 这是相当少量的代码。 因此,在第一次授权请求之后,服务器将在响应标头中的 key set-cookie下使用 cookie 进行响应。 有用的信息在set-cookie key 的值中,从开始到第一次出现; 字符(稍后会详细介绍)。 例如, set-cookie的值可能如下所示:

sessionid=asfweggv7bet4zw11wfpb4u415yx; expires=Fri, 06 Nov 2020 11:14:40 GMT;

您需要保存它并在下次授权请求中每次使用。

为了保存它,我创建了一个方法,您应该在第一个授权响应后调用它。 您可以在每次响应后调用它(如果您有通用的响应处理),因为如果服务器没有发送新的 cookie,它不会与现有的 cookie 混淆。***

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
const kCookie = 'my_fancy_cookie';
// ...
void _storeCookie(http.Response response) async {
  String rawCookie = response.headers['set-cookie'];
  if (rawCookie != null) {
    int index = rawCookie.indexOf(';');
    String cookie = (index == -1) ? rawCookie : rawCookie.substring(0, index);
    await FlutterSecureStorage().write(key: kCookie, value: cookie);
  }
}

然后在我发送我的请求之前,我将 cookie 添加到标头中:

// endpoint, payload and accessToken are defined earlier
cookie = await FlutterSecureStorage().read(key: kCookie);
http.Response response = await http.post(
  endpoint,
  body: json.encode(payload),
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer ' + accessToken,
    'cookie': cookie,
  }
);

请记住在注销后从安全存储中清除 cookie。 :)

*** - 服务器可能会更改会话 ID(以减少我们还不需要考虑的点击劫持之类的事情),因此最好继续从每个响应中提取 cookie。

浏览器正在保存/发送 Django 会话 cookie。 颤振应用程序 http 请求不是。

“持久”连接并不意味着它会为您处理 cookie。 您需要自己完成此操作或找到可以执行此操作的第三方库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM