Reputation: 847
I need to send my token for my API. I save my token in SharedPreferences and I can recupered this. My API need one, with the Bearer but how do ?
I tested with Authorization, Http etc.
Methods To save in SP
Future<bool> setToken(String value) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString('token', value);
}
Future<String> getToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('token');
}
Future<Candidate> candidateAuth({Map map}) async {
String url = 'http://10.0.2.2:3000/v1/api/auth/candidate';
await http
.post(url,
headers: {
'Content-type': 'application/json',
'Accept': 'application/json'
},
body: jsonEncode(map))
.then((response) {
if (response.statusCode == 201) {
token = Candidate.fromJson(json.decode(response.body)).token;
Candidate().setToken(token);
return Candidate.fromJson(json.decode(response.body));
} else {
throw Exception('Failed auth');
}
});
}
}
My API Call :
Future<List<Theme>> getThemes() async {
String url = 'http://10.0.2.2:3000/v1/api/theme';
String token;
Candidate().getToken().then((value) {
token = value;
});
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print(response);
if (response.statusCode == 200) {
List themesList = jsonDecode(response.body);
List<Theme> themes = [];
for (var themeMap in themesList) {
themes.add(Theme.fromJson(themeMap));
}
return themes;
} else {
throw Exception('Failed to load themes');
}
}
My API return error 401 : unauthorized
Upvotes: 37
Views: 112409
Reputation: 1
I spent complete one day , Just Tell your backend developer to do this.
when Dio/Http sends headers it will lowerCasing all headers keys.
So if you have access to the server you must lowercase your key.
Eg. [PHP] $token = array_change_key_case($this->input->request_headers(), CASE_LOWER)['authorization'];
@Flutter code
final response = await http.get(url, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $token', });
Upvotes: 0
Reputation: 27
I had similar issue don't know if it will work for everyone, changing the url to https:// solved it.
Upvotes: 1
Reputation: 36
The cleaner code
String? token = await Candidate().getToken();
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
await http.get(url, headers: requestHeaders);
Then if you want the responce or the data come from the backend you can replace await http.get(url, headers: requestHeaders);
by var responce = await http.get(url, headers: requestHeaders);
and use the responce.
Upvotes: 2
Reputation: 531
This is the other possible solution for the problem. You have to wait response of getToken() function before continuing. You can accomplish it in two different ways. Either use "then" or "await".
Future<List<Theme>> getThemes() async {
String url = 'http://10.0.2.2:3000/v1/api/theme';
String token;
Candidate().getToken().then((value) {
token = value;
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print(response);
if (response.statusCode == 200) {
List themesList = jsonDecode(response.body);
List<Theme> themes = [];
for (var themeMap in themesList) {
themes.add(Theme.fromJson(themeMap));
}
return themes;
} else {
throw Exception('Failed to load themes');
}
});
}
Upvotes: 3
Reputation: 1455
You just need to add the authorization field into the request header:
var token = await getToken();
http.post(
"$url",
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer $token',
},
encoding: Encoding.getByName("utf-8"),
).then((response) {
if (response.statusCode == 200) {
print(json.decode(response.body));
// Do the rest of job here
}
});
Upvotes: 6
Reputation: 9
final response = await http.get(url);
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
//print(body);
final Iterable json = body;
return json.map((country) {
return Country.fromJson(
country); // if you use "{}", you must use return
}).toList();
Upvotes: -2
Reputation: 773
This is a sample for a post request. You just need to add the header 'Authorization': 'Bearer $token'
final response = await http.post(
url,
headers: {'Authorization': 'Bearer $token'},
);
Upvotes: 2
Reputation: 1299
Also you can use this method
String token = await Candidate().getToken();
final response = http.get(url,
headers: {HttpHeaders.contentTypeHeader: "application/json", HttpHeaders.authorizationHeader: "Bearer $token"});
Upvotes: 15
Reputation: 96
The problem is that you assign your token in a different way.
When you do this await asyncFunction();
Dart will wait till it is complete. But, when you do like this asyncFunction().then((value) => print)
this tells Dart that it can continue executing your code, and when that asyncFunction is completed than print the value.
This is what happens on your case with
Candidate().getToken().then((value) {
token = value;
});
Here is a example, execute it on Dart Pad.
Upvotes: 2
Reputation: 2341
token
might not be set by the time it invokes http.get
. Change it to
String token = await Candidate().getToken();
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print(response);
So that it is for sure set with right value.
Upvotes: 88