Reputation: 12854
Just started implementing API(get, post mostly) in Flutter. I was getting the post API response well but for GET API, I am getting 401. The code is given below:
import 'package:http/http.dart' as http;
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjgiLCJVc2VyRGV2aWNlSWQiOiI0NTVENDY3Rjc4MjI0QjlDOERFN0JDMjFFNjREQjVEQyIsIkZ1bGxOYW1lIjoiQW5keSBNZW1iZXIiLCJQaG9uZSI6IjA0MjM5OTkzMzMiLCJlbWFpbCI6Im1rYWJpckBmYXFpLmNvbS5hdSIsInN1YiI6IjA0MjM5OTkzMzMiLCJqdGkiOiJkZGY3NDM4OC03YzE4LTQyZjktODdkMC0yMGQzY2NjNDE2ZGIiLCJuYmYiOjE2MjQ5NDIxNzAsImV4cCI6MTYyNDk2Mzc3MCwiaWF0IjoxNjI0OTQyMTcwfQ.I9pR2HZbKlOwl_9Z5O5AE8kZh0o5SdTOxsvTsY28SUk";
var headers = {
'AuthToken': token,
'accept': 'application/json',
};
final response = await http.get('http://api.orca.faqdev.com.au/api/account/Dashboard' , headers: headers);
Two things regarding the API :
Anyone can guess what happens here in Flutter? BTW, I am new in Flutter.
Upvotes: 1
Views: 1103
Reputation: 4320
Fundamentally, this comes down to HTTP header names not being case sensitive, and the API server not respecting this.
The header at issue is AuthToken
; if sent through verbatim, the server will accept it but if not, the server will reject it. The Dart http
package sends through the header in lower case (authtoken
) whereas Swift sends through the header maintaining the case (though noting that the names are case insensitive).
Compare:
curl \
--header 'AuthToken: <redacted>' \
--silent \
--verbose \
http://api.orca.faqdev.com.au/api/account/Dashboard > /dev/null
* Trying 52.63.81.235...
* TCP_NODELAY set
* Connected to api.orca.faqdev.com.au (52.63.81.235) port 80 (#0)
> GET /api/account/Dashboard HTTP/1.1
> Host: api.orca.faqdev.com.au
> User-Agent: curl/7.64.1
> Accept: */*
> AuthToken: <redacted>
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Server: Microsoft-IIS/10.0
< X-Powered-By: ASP.NET
< Date: Tue, 29 Jun 2021 06:53:33 GMT
< Content-Length: 1697
<
{ [1697 bytes data]
* Connection #0 to host api.orca.faqdev.com.au left intact
* Closing connection 0
vs:
curl \
--header 'authtoken: <redacted>' \
--silent \
--verbose \
http://api.orca.faqdev.com.au/api/account/Dashboard > /dev/null
* Trying 52.63.81.235...
* TCP_NODELAY set
* Connected to api.orca.faqdev.com.au (52.63.81.235) port 80 (#0)
> GET /api/account/Dashboard HTTP/1.1
> Host: api.orca.faqdev.com.au
> User-Agent: curl/7.64.1
> Accept: */*
> authtoken: <redacted>
>
< HTTP/1.1 401 Unauthorized
< Transfer-Encoding: chunked
< Server: Microsoft-IIS/10.0
< X-Powered-By: ASP.NET
< Date: Tue, 29 Jun 2021 06:54:42 GMT
<
{ [5 bytes data]
* Connection #0 to host api.orca.faqdev.com.au left intact
* Closing connection 0
The best solution is to configure the API server to treat all headers as case insensitive (as per the spec), then it will work for all clients.
If you absolutely positively can't do that, there is an option to use the HttpClient
provided by dart:io
, and in that scenario your implementation would end up something like:
import 'dart:convert';
import 'dart:io';
...
final client = HttpClient();
final request = await client
.getUrl(Uri.parse('http://api.orca.faqdev.com.au/api/account/Dashboard'));
request.headers.set('AuthToken', '<redacted>', preserveHeaderCase: true);
final response = await request.close();
final chunks = await response.transform(utf8.decoder).toList();
final body = chunks.join('');
client.close();
// handle the response
print(body);
Note the use of preserveHeaderCase
on the HttpHeaders.set
method
Upvotes: 2