在flutter升级后,Dart HttpClient具有基本身份验证问题

时间:2018-05-12 10:58:47

标签: dart flutter

经过大量的浏览和阅读文档之后,我遇到了这个answer,直到我升级了。

我当前的问题是凭据无法到达我的服务器。 IntelliJ错误:

I/FlutterActivityDelegate( 6944): onResume setting current activity to this
D/EGL_emulation( 6944): eglMakeCurrent: 0xa7f852a0: ver 2 0 (tinfo 0xa7f83250)
I/flutter ( 6944): doing login with credentials:: W and T
I/flutter ( 6944): my_response is:: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
I/flutter ( 6944): <title>429 Too Many Requests</title>
I/flutter ( 6944): <h1>Too Many Requests</h1>
I/flutter ( 6944): <p>1 per 1 minute</p>
E/flutter ( 6944): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 6944): type '(Exception) => void' is not a subtype of type '(Object) => FutureOr<dynamic>'

请求的服务器输出是:

 credentials::  - 
 192.168.1.175 - - [12/May/2018 10:56:23] "GET /users/login HTTP/1.1" 401 -
 192.168.1.175 - - [12/May/2018 10:56:23] "GET /users/login HTTP/1.1" 429 -

LE:&#34;凭证:: - &#34;是在服务器的身份验证级别完成的打印。 LLE:卷曲请求正常工作

curl -u 123456:password http://localhost:5000/users/login 
{
 "is_logged_in": true, 
 "last_login": 1525980360
}

回应是:

credentials:: 123456 - password
127.0.0.1 - - [12/May/2018 13:00:50] "GET /users/login HTTP/1.1" 200 -

我使用与上面提供的链接完全相同的代码。

1 个答案:

答案 0 :(得分:3)

以下是在评论中结束讨论的摘要答案。

似乎Too Many Requests错误可能是由HTTP客户端与需要授权的服务器通信的典型行为触发的。

GET ->
    <- 401 Unauthorized + scheme + realm (and nonce if applicable)
GET with Authorization header ->
    <- 200 OK (if credentials are valid)

似乎服务器可能已将第一个GET / 401计入某种每分钟请求限制。

但是,来自curl的请求是成功的,可能是因为curl抢先发送了带有第一个GET的Authorization标头,而不是等待被问到401.只要授权方案是{{1},它就可以这样做因为它不需要服务器的任何信息。 (它不适用于Basic,因为如果没有与401一起发送的随机数,它无法计算授权标头。)

问题出现了,有没有办法在Digest中预先发送基本身份验证?

正常方式 - 仅发送以响应401

package:http

抢占方式 - 仅适用于基本身份验证

// create an IOClient with authentication
HttpClient inner = new HttpClient();
inner.authenticate = (uri, scheme, realm) {
  inner.addCredentials(
      uri, realm, new HttpClientBasicCredentials(username, password));
};
http.IOClient client = new http.IOClient(inner);

// and use it like this
http.Response response = await client.get('https://api.somewhere.io');
// todo - handle the response

用实用方法

// use the normal http.get method, but add the header manually, with every request
http.Response response = await http.get(
  'https://api.somewhere.io',
  headers: {'authorization': basicAuthenticationHeader(username, password)},
);
// todo - handle the response