Facing some issues in Flutter REST API using with JWT token - flutter

I'm facing some issues in Flutter REST API using with JWT token
Here the header authentication was not passing properly. But it working good in Postman
**Example Code:**
String url = "project URL";
String token = "generated jwt token";
var headers = {
'Authorization': token,
'Cookie': 'ci_session=u17u9effeqk5fdhl1eqdh4jsmu3o3v29'
};
var request = http.Request('GET', Uri.parse(url));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
If I try without the JWT token by removing it in the backend it's working properly. But I need to work with JWT.
Can anyone please help to fix this issue?

I use dio package to work with the same...
// Import dio package
Future<void> function() async {
Dio dio = new Dio();
String url = 'example.com';
try {
final response = await dio.post(
url,
options: Options(
headers: {'Authorization': 'Bearer $userToken'}, //This is where you define your header and provide jwt token
),
);
} on DioError catch (error) {
if (error.response!.statusCode == 401) {
print(error.response.toString());
throw Error();
}
print(error);
throw Error();
}
}
}
The package can be found here https://pub.dev/packages/dio
Feel free to clear up any confusions

The most likely issue here is the value that you give in your header.
For Bearer tokens, the value given in the Authorization header must be Bearer followed by the value of your token. If you did not implement some specific/homemade authorisation function in your backend, this must be what is expected to be received.
Try replacing 'Authorization': token, by
'Authorization': `Bearer $token`,
and it shouldd work as intended.

Related

One or more validation errors occurred in a get request with Basic Authentication authorization

I am working with basic authentication in a get request, and it takes parameters, but it throws the following error as a status code and response body.
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-5bebf6cfcb0e1cec5306c5dbff1cf6c0-c432aba0a422c830-00","errors":{"password":["The password field is required."],"user_name":["The user_name field is required."]}}.
I don't know what it means and what should I fix in my code. Can anybody help me, here is my code:
String basicAuth =
'Basic ${base64.encode(utf8.encode('$_email:$encodedPassword'))}';
var queryParams = {
'domain_name': 'domainName',
'token': 12345.toString(),
};
final uri =
Uri.https(baseUrl, '/api/Employee/validate_user', queryParams);
final res = await http.get(uri, headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.authorizationHeader: basicAuth,
});
if (res.statusCode == 200) {
debugPrint(res.body);
}else {
debugPrint("Status " + res.statusCode.toString());
debugPrint(res.body);
}

Flutter http can't get Bearer Token from .NET Api

I am starting flutter mobile development and have problem with http package http calls. I already have working API written in .NET with included Micorosft Identity. My goal is to create flutter mobile app that gets data from that API with authorizauion. I have problems implementing username-password authorization to get Token from API. Same API call works on Postman and in my existing Xamarin Forms App. Same problem with http call where in its header I use token which I get from Postman. Using VS Code, all packages installed, can retrive sample data from openweathermap.org in same flutter app. My code is:
Recive Bearer Token from API:
Future<String> authorization(String username, String password) async {
Uri uri = Uri.parse('https://myapi/token');
var request = http.MultipartRequest('POST', uri);
request.fields.addAll({
'grant_type': 'password',
'username': username,
'password': password,
});
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
Map<String, dynamic> auth =
jsonDecode(await response.stream.bytesToString());
return auth['access_token'];
} else {
return "";
}
}
GET Cars Data from API:
Future<String> getCars() async {
Uri uri = Uri.parse('https://myapi/api/getcars');
var token =
'WorkingToken';
http.Response response = await http.get(uri, headers: {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer $token",
});
return response.body;
}
Microsoft Identity Authorization request expects application/x-www-form-urlencoded content.
Future<String> authorization(String username, String password) async {
final response = await http.post(
Uri.parse('https:/host/path/token'),
headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded',
},
body: <String, String>{
'grant_type': 'password',
'username': username,
'password': password,
},
encoding: Encoding.getByName('utf-8')
);
if (response.statusCode == 200) {
return jsonDecode(response.body)['access_token'];
} else {
throw Exception(response.reasonPhrase);
}
}
Your question is very general and your problem depends on your response data. Of course, I did not realize that you have a problem receiving the token or using the token as a header for another api!
But since you are just starting to use Flutter, I suggest you to use the Chopper Library to work with HTTP services and api.
It's very simple and fase.

Flutter dio image upload not working throws server 401 error, but works in postman

This is my postman request with a header Authorization Bearer Token.
I am trying to upload the image, everything is set up as mentioned with the documents dio and exactly the same as the postman parameter, but it is throwing a 401 error, it is giving me an Unauthorized error, it would appear that it is not taking the token to process and upload the file. I was reading and moving options that were mentioned in post, but unfortunately I have not been successful.
I would be very grateful if someone could give me some guidance and help me to get the process done.
My dio request:
employeeAttachFile(File file) async {
final SecureStorage _secureStorage = SecureStorage();
final token = await _secureStorage.readToken('token');
final String uri = '${ApiPaths.basisApi}${ApiPaths.addEmployeesFile}15';
String fileName = file.path.split('/').last;
print(fileName);
FormData data = FormData.fromMap({
"file": await MultipartFile.fromFile(
file.path,
filename: fileName,
),
});
Dio dio = new Dio(BaseOptions(
headers: {"Authorization": token}, contentType: "application/json"));
await dio.post(uri, data: data).then((response) {
var jsonResponse = jsonDecode(response.toString());
print(jsonResponse);
}).catchError((error) => print(error));
}
This is my error:
Try
{'Authorization': 'Bearer $token'}

Can't able to call simple API

I just want to call simple API but can't able to call. If I tried to call in Postman then get proper response.
Look at my code
Future<AppServiceModel> getAllItems({String pageID = ""}) async {
final String _url = "http://www.textsite.com/api/app-view?page_id=";
final finalURL = Uri.encodeFull(_url);
try {
return http.get(finalURL, headers: {
HttpHeaders.contentTypeHeader: 'application/x-www-form-urlencoded',
HttpHeaders.acceptHeader: "application/json",
HttpHeaders.authorizationHeader: 'Bearer $accessToken'
}).then((response) {
Map<String, dynamic> _resDic =
Map<String, dynamic>.from(json.decode(response.body));
print('===>> Response : $_resDic');
return AppServiceModel.fromJson(_resDic);
});
} catch (e) {
print("Error: $e");
return null;
}
}
I also tried to pass QueryParameters by following How do you add query parameters to a Dart http request?
But each time get response
Response : {code: 7, msg: Your login session has expired. Please login again to continue., data: []}
I'm damm sure, passing right TOKEN.
Below is output of Postman

How to get the token from firebase_auth

I'd like to get the auth token from firebase (email and password auth) to authenticate in my firebase cloud function. It seems like the functions getIdToken() and getToken() are both not working for firebase_auth package.
is there an other function or is there even a better idea to make sure only authenticated users can trigger the cloud functions?
var token = await FirebaseAuth.instance.currentUser.getIdToken();
var response = await httpClient.get(url,headers: {'Authorization':"Bearer $token"});
I agree with #Doug on this one - callable wraps this for you and will be easier -, but my use case required me to make HTTPS calls (onRequest in Functions). Also, I think you're just in the correct path - but you're possibly not checking it in your Cloud Functions.
In your app, you'll call:
_httpsCall() async {
// Fetch the currentUser, and then get its id token
final user = await FirebaseAuth.instance.currentUser();
final idToken = await user.getIdToken();
final token = idToken.token;
// Create authorization header
final header = { "authorization": 'Bearer $token' };
get("http://YOUR_PROJECT_BASE_URL/httpsFunction", headers: header)
.then((response) {
final status = response.statusCode;
print('STATUS CODE: $status');
})
.catchError((e) {
print(e);
});
}
In your function, you'll check for the token:
export const httpsFunction = functions.https.onRequest((request, response) => {
const authorization = request.header("authorization")
if (authorization) {
const idToken = authorization.split('Bearer ')[1]
if (!idToken) {
response.status(400).send({ response: "Unauthenticated request!" })
return
}
return admin.auth().verifyIdToken(idToken)
.then(decodedToken => {
// You can check for your custom claims here as well
response.status(200).send({ response: "Authenticated request!" })
})
.catch(err => {
response.status(400).send({ response: "Unauthenticated request!" })
})
}
response.status(400).send({ response: "Unauthenticated request!" })
})
Keep in mind:
If I'm not mistaken, those tokens are valid for 1 hour, if you are going to store them somewhere, just be aware of this. I've tested locally and it takes around 200~500ms - every time - to get only the id token, which in most cases are not that big of overhead - but is significant.
It's going to be easiest for you to use a callable function, since that lets you:
Automatically send the current user's uid in the request.
Know very easily on the function side if a UID was provided in the request, and refuse service if none was provided.
The flutter plugin is here.
You should be able to do the equivalent work yourself, though, since callable functions are just a wrapper around normal HTTP connections. It's possible for you to get the ID token of the logged in user.
import 'package:firebase_messaging/firebase_messaging.dart';
.
.
.
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
#override
Future<void> initState() {
super.initState();
_firebaseMessaging.getToken().then((token) {
assert(token != null);
print("teken is: " + token);
});
}
Get your token from firebaseAuth and put in a string.
Future<Details> getDetails() async {
String bearer = await FirebaseAuth.instance.currentUser!.getIdToken();
print("Bearer: " + bearer.toString());
String token = "Bearer ${bearer}";
var apiUrl = Uri.parse('Your url here');
final response = await http.get(apiUrl, headers: {
'Authorization' : '${token}'
});
final responseJson = jsonDecode(response.body);
return Details.fromJson(responseJson);
}