【问题标题】:Flutter http Maintain PHP sessionFlutter http 维护 PHP 会话
【发布时间】:2018-10-22 06:43:18
【问题描述】:

我是新来的颤振。基本上我正在为我的 Web 应用程序使用代码 Igniter 框架。我为我的网络应用程序创建了 REST API,在用户使用 API 登录后,所有方法都会检查 session_id 如果它存在则继续,如果不存在则给出

{ ['status'] = false, ['message'] = 'unauthorized access' }

我正在使用颤振创建应用程序,当我使用颤动的 http 方法时,它会更改每个请求的会话。我的意思是,它不维护会话。我认为它每次都会破坏并创造新的联系。这是我用于 api 调用获取和发布请求的 thr 类方法。

class ApiCall {  
  static Map data;
  static List keys;

static Future<Map> getData(url) async {
 http.Response response = await http.get(url);
 Map  body =  JSON.decode(response.body);
 data = body;
 return body;
}

static Future postData(url, data) async {
Map result;    
http.Response response = await http.post(url, body: data).then((response) {
  result = JSON.decode(response.body);
}).catchError((error) => print(error.toString()));

data = result;
keys = result.keys.toList();

return result;  
}

我想发出 API 请求,然后存储 session_id, 是否可以在服务器上维护会话,以便我可以在自己的网络应用程序上管理身份验证。

【问题讨论】:

标签: flutter


【解决方案1】:

HTTP 是一种无状态协议,因此服务器需要某种方式来识别客户端在向服务器发出的第二个、第三个和后续请求时。在您的情况下,您可能会使用第一个请求进行身份验证,因此您希望服务器在后续请求中记住您,以便它知道您已经通过身份验证。一种常见的方法是使用cookies

Igniter 发送一个带有会话 id 的 cookie。您需要从每个响应中收集它并在下一个请求中将其发送回。 (服务器有时会更改会话 ID(以减少我们还不需要考虑的点击劫持等事情),因此您需要不断从每个响应中提取 cookie。)

cookie 作为一个名为set-cookie 的 HTTP 响应标头到达(可能不止一个,但希望不是为了简单起见)。要发回 cookie,您需要在后续请求中添加一个名为 cookie 的 HTTP 请求标头,复制您从 set-cookie 标头中提取的一些信息。

希望 Igniter 只发送一个 set-cookie 标头,但出于调试目的,您可能会发现使用 response.headers.forEach((a, b) =&gt; print('$a: $b')); 将它们全部打印出来很有用。你应该找到Set-Cookie: somename=abcdef; optional stuff。我们需要将字符串提取到,但不包括;,即somename=abcdef

在下一个和后续请求中,将请求标头添加到您的下一个请求 {'Cookie': 'somename=abcdef'},方法是将您的 post 命令更改为:

http.post(url, body: data, headers:{'Cookie': cookie})

顺便说一句,我认为您在上面的代码中 awaitsthens 不匹配。通常,如果它们应该是顶级函数,那么您不希望在类中使用静态变量。相反,您可以创建一个 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);
    }
  }
}

【讨论】:

  • 您能否详细说明一下,我是 Flutter 和 cookie 的新手。那么,这意味着在每次请求后都会与不会保持会话活动的站点建立新连接?
  • 这实际上并不特定于 Dart 或 Flutter。这是一个 HTTP 的事情。 HTTP 是一种无状态协议,可随时与服务器建立新连接。因此,您没有与服务器的永久连接。 Cookie 就是这个问题的答案——把它们想象成一张票。每次服务器向您发送响应时,它都会向您发送一张票。如果你把那张票寄回去,它就知道是你,因为你是它给那张票的唯一人。当服务器接收到一个没有 cookie 的请求时,它假定它是一个新订阅者并创建一个新会话,这就是为什么不断看到新会话的原因。
  • 更详细地编辑了答案
  • 如果这个答案有用,通常会支持它和/或接受它。如果没有用,请告诉我。
  • @Germán 请参阅 Iarly 对多个 cookie 的回答 here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多