Can't get auth token stored in flutter secure storage to headers - flutter

I am making flutter app using API and I have a problem. When I want to get auth token to make request, flutter says that "Expected a value of type 'String', but got one of type '_Future'". How can I make a request with auth token without that error?
My login function, where I write the token:
loginUser() async {
final storage = new FlutterSecureStorage();
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/login");
await http
.post(uri,
headers: {"Content-Type": "application/json"},
body: jsonEncode({
"username": emailController.text,
"password": passwordController.text
}))
.then((response) async {
if (response.statusCode == 200) {
var data = json.decode(response.body);
await storage.write(key: "token", value: data["token"]);
print(data["token"]);
} else {
print(json.decode(response.body));
}
});
}
My getdata function, where i use the token:
getdata() async {
final storage = FlutterSecureStorage();
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/countries");
await http.get(uri, headers: {
"Content-Type": "application/json",
"Authorization": await storage.read(key: "token")
});
}

try this code
String token = await storage.read(key: 'token');
//make sure if there is no Bearer just token in that case just pass the token
var headers = {
'accept': 'application/json',
'Authorization': 'Bearer ${token}',
};
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/countries");
Response response = await http.get(
uri,
headers: headers
);
print (response);

Related

Getting empty response body from a http post request to an api

This is my code. The goal is to get the link with file id.
// body parameter
Map<String, dynamic> body = {'file_id': 123};
String jsonBody = json.encode(body);
// response request
var download_response = await http.post(
Uri.parse('https://api.opensubtitles.com/api/v1/download'),
headers: {
'Content-Type': 'application/json',
'Api-Key': 'yCTZwGASncUthpMkMkbQDjcUdrrM2r8v'
},
body: jsonBody,
);
// print
debugPrint(download_response.body.toString());
I think I should be getting a JSON data response which I'm getting properly with postman but in flutter I'm getting empty response.
Things I tried:
encoding the body with jsonencode
correct syntax formatting
writing the body in plain json string
var headers = {
'Api-Key': 'yCTZwGASncUthpMkMkbQDjcUdrrM2r8v',
'Content-Type': 'application/json'
};
var request = http.MultipartRequest('POST', Uri.parse('https://api.opensubtitles.com/api/v1/download'));
request.fields.addAll({
'file_id': '123'
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}

how to send token while post request

have a great day, i have a silly problem, don't mind as i am noob. ok my problem is, i have a token which i received after i login, now i have to post a data but for that i have to include this token in my header, but i don't know how to....
here is my token, which i received after login as response
{
"token": "8d18265645a87d608868a127f373558ac2e131a6"
}
Here, i have to implement in flutter
apiData.ApiData app = apiData.ApiData();
final String apiURl = app.api;
SharedPreferences pref = await SharedPreferences.getInstance();
String? email = pref.getString("useremail");
String? token = pref.getString('token');
String date = DateFormat("yyyy-MM-dd").format(DateTime.now());
String time = DateFormat("Hms").format(DateTime.now());
print(time);
print(date);
dynamic response =
await http.post(Uri.parse(apiURl + "/api/user-log/"), body: {
'user': email,
'start_time': time,
'start_date': date,
});`
Here in the documentation you can found the following snippet, where the headers are sent with the HTTP request:
Future<http.Response> createAlbum(String title) {
return http.post(
Uri.parse('https://jsonplaceholder.typicode.com/albums'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'title': title,
}),
);
}
Add header in the post method as below:
var headers = {
'authorization': token,
"Accept": "application/json"
};
dynamic response =
await http.post(Uri.parse(apiURl + "/api/user-log/"),headers: headers), body: {
...
});
final response = await http.get(
Uri.parse(apiURl + "/api/user-log/"),
body: {}
headers: {
HttpHeaders.authorizationHeader: "<Your token here>",
},
);
Documentation here

I would like to upload a image and profile data in Multipart/Formdata format in flutter when hit a api i got response failed

Here is my post api code i try to upload file (image from image picker)and profilePojo(data like username ,fname, lastname etc.) when i run code i got result failed .
'''
void addData(final profilePojo) async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String token = preferences.getString('token');
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"profilePojo":profilePojo,//profilePojo means i pass heaar string of data on button click
});
String url =pass here url
http
.post(
url,
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token',
// "Content-Type":"multipart/form-data",
"accept": "application/json",
},
body: formData.toString()
)
.then((response) {
if (response.statusCode == 200) {
var myData = json.decode(response.body);
if(myData['result']=="success"){
setState(() {
print(myData);//print response success
_showDialog();
getData();
});}
else{
print(response.statusCode);
print(myData);
}
} else {
print(response.statusCode);
print("object");
}
});
}
'''
I'm currently using dio for this kind of requests, here is my example:
final futureUploadList = imageList.map((img) async {
print(img.path);
return MultipartFile.fromFile(img.path);
});
final uploadList = await Future.wait(futureUploadList);
FormData data = FormData.fromMap({
"images": uploadList
});
dio.post('/images',
data: data, options: Options(headers: {'Authorization': 'Bearer abcd'}));

How to remove quotation and symbols while decoding from JSON value? Flutter

This is the code to get my auth token.
Future <String> getToken() async{
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('token');
}
When i print the token it gives me this json value with double quotation mark.
I/flutter (14710): "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiZDQzZjFjNWZjZDQxYjIzYzllNGU2ZWIyZjQ1M2FmZDgwOTJiNGZmNDAyYjI0OTBmM2RiYTUzMTgzYTU2ODZjNTNiNzVmMDY3ZmIzMmNjMjUiLCJpYXQiOjE1OTA0MDg2NjksIm5iZiI6MTU5MDQwODY2OSwiZXhwIjoxNjIxOTQ0NjY5LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.3YYdR8P1_XzK--VLAwT5gxmkyLZPMuvQhzQQ5OOl_nv0jriPwFY9sqHdL_wiqpAA5vtgBOnyAwZ2kSI_BgDzsKZzY2vMVa47Tyuz87uEFZ7-aHYvNY_r4T_gIkwAuLwc8qN2kuytFjEtuq-iQUiWgEzp5y2n3BDlzXZ7rZi5Xp1_y_6_ysII9RQtX37LuDFt3AIRbYLGDBAilPHi0iJB_jQqWqH8J1mUzCsArj2VuSel7kERqpwFz-SwOOS4EA7CaoOuOlleOpynBalTK9vm1vU3n81K4TAgNq-Mg9CsiFMVQULURdmku7-2gcc3VS8vBXo9OlEgzqmGjLDvIy8_-LCcwuoSVC2DL2t2PIcNUDKQsBu1GBPQ99wzHcnyEpvjVRkg7v4zQWtlIUY6PcLjNf_vnfuXuCERAwBwjS86T7n8ZscfmVVebISVvAKyDN6YhW41hnUw-AZYRLtuhbE8Z48V0tLfLw9aeVr-Qe2mlaYj0LqGYlqBLqUtRl9HSaA9USa6tQ1KQJvF5_6JPcIBJuSkEsrY9n1xhnCViAiyFVF4XWbtToULn69B2UtoXw1X8y_Wek_T7D7t0fi5KWKj8QHO6yI3ZIWViERS2K6n7mnL_3z_7CNeewVxmqMXNdeWl7yPmAMzUAv6z7pWm-R1Qpv7tNVj4-FfQAk3vOm56hE"
This is how i used the token you get the post from api but it isnt working.
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
code is wrong in a way, think you have async and then both on the same function, why?
ApiService().getToken().then((value){
token = value;
});
here you're saying I want token and I don't need to be awaited then you go and try to use that variable
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
see in flutter every async-await works like event loop in javascript
I write async
normal code
using then in 1. function
dependent code in 1. as async-await
what will be the output?
event loop will be having 1,2,3,4 as async functions
first, it will run 1 and as soon as it receives normal code it runs normally but if it receives then it will understand that this result is not important so let me do rest of the work and will come back to execute 3rd then function so it will run 4 and then 3rd function
but you want token so
ApiService().getToken().then((value){
token = value;
});
replace this to
token = await ApiService().getToken();
your service might need token and that's the reason it's not 200 status code.
If you just want to remove the "" from the string, then just use the replaceAll method
String string = '"foo"';
//Output: 'foo'
string.replaceAll('"', '');

How to get the token for register api in flutter

I am having the Url for Token generation,by using http post i am getting the token.now my problem was i have to use the generated token as header in register api(another api).
Future<Map<String, dynamic>> fetchPost() async {
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
return responseJson;
}
here i am getting the token i want to use that token to register api
Future<Register> fetchPost() async {
print('feg');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: "Bearer token",
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}
this is the post method for register api,i want to use previously generated bearer token in above api headers.
Another option, is use secure storage whit Keychain (Android) and Keystore (iOS)
https://pub.dev/packages/flutter_secure_storage
Add in your pubspec.yaml
dependencies:
flutter_secure_storage: ^3.2.1+1
And in your code, import library and save
Future<Map<String, dynamic>> fetchPost() async {
final storage = FlutterSecureStorage();
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
/// Write token in token key with security
await prefs.write(key: 'token',value: responseJson['token']);
return responseJson;
}
If you need read, use this code:
Future<Register> fetchPost() async {
final storage = FlutterSecureStorage();
print('feg');
String token = await storage.read(key: 'token');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: token,
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}
you can save the generated token in the shared preferences. Then you can use it in any request later.
first add in pubspec.yaml
dependencies:
shared_preferences: ^0.5.3+4
then import it in your code:
import 'package:shared_preferences/shared_preferences.dart';
so when you get your token
Future<Map<String, dynamic>> fetchPost() async {
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
SharedPreferences prefs = await SharedPreferences.getInstance();
//now set the token inside the shared_preferences
//I assumed that the token is a field in the json response, but check it before!!
await prefs.setString('token',responseJson['token']);
return responseJson;
}
and when you need to send the request just get the token from the shared_preferences:
Future<Register> fetchPost() async {
print('feg');
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: token,
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}