flutter login with dio package - flutter

i try to login to the api with dio and i cant handle it
my scenario is:
login with user name,password and server returned session like this:
{
"function": "request_session_generate",
"params": {
"username": "myuser",
"password": "mypass"
}
}
and when send request post method returned session like below code:
{
"result": 0,
"data": {
"session": "mysession...",
"session_status": "generated"
}
}
and second post method for validate this session ... put the session and otp code(google authenticator) like this:
{
"function": "request_session_validate",
"params": {
"session": "mysession",
"otp": "123456"
}
}
when put the session in to the session params server returned:
{
"result": 0,
"data": {
"session": "newSession",
"session_status": "validated"
}
}
how can get the session in the body response first method and use it in the second function for validate
my first function implement code :
class ApiClient {
final Dio _dio = Dio();
Future<Response?> login() async {
try {
Response response = await _dio.post(
'myserver/api',
options: Options(
headers: {
"apikey": "00000000-0000-0000-0000-000000000000",
},
),
data: {
"function": "request_session_generate",
"params": {
"username": "myuser",
"password": "mypass"
}
},
);
//returns the successful user data json object
if(response.statusCode == 200){
return response.data;
}
} on DioError catch (e) {
//returns the error object if any
return e.response!.data;
}
return null;
}
and my implemention for validate and not worked:
Future<Response?> validate() async {
try {
Response responsevalidate = await _dio.post(
'myserver/api',
data: {
"function": "request_session_validate",
"params": {
"session": "mysession",
"otp": "123456"
}
},
);
//returns the successful user data json object
return responsevalidate.data;
} on DioError catch (e) {
//returns the error object if any
return e.response!.data;
}
//IMPLEMENT USER LOGIN
}
how can get session in first function and use it in second function for validate?
use the json decode or something else ?
thank you for help me

Related

HandshakeException: Connection terminated during handshake

I'm developing my first Flutter mobile app, and I'm facing an error trying to fetch data from API REST.
I set 2 get request using HTTP packages:
-the first is a single request, and it's fetching 'work orders' with attributes immediately available;
-the second one is another get request that fires per every 'work order' retrieved from the first request that take others attributes.
Basically, I run the first get request and I made a for loop to fire the second get request for all data.
So, the first request is working fine, instead the second one is giving me the following error for every time it fires:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled
Exception: HandshakeException: Connection terminated during handshake
The strange things are that it works, but I can't anyway render the widget with the error.
This is the code I used for fetching data:
Future<void> fetchAndSetWorkOrders([bool filterByUser = false]) async {
var url = Uri.parse(
'https://API_URL/wo?fields=id,code,description,statusCode,actionType,assignedTo&filter[wo][statusCode]=REQUEST');
try {
var response = await http.get(
url,
headers: {
"token": authToken,
},
);
var extractedData = json.decode(response.body) as Map<String, dynamic>;
final List<WorkOrder> loadedWorkOrders = [];
if (extractedData['data'] == null) {
return;
}
extractedData['data'].forEach(
(attribute) async {
var actionType_url = Uri.parse(attribute['relationships']
['actionType']['links']['related']);
var actionType_response = await http.get(
actionType_url,
headers: {
"token": authToken,
},
);
var actionTypeData = json.decode(actionType_response.body) as dynamic;
var actionType_code =
actionTypeData['data']['attributes']['code'];
print(actionType_code);
loadedWorkOrders.add(
WorkOrder(
id: attribute['id'],
code: attribute['attributes']['code'],
description: attribute['attributes']['description'],
statusCode: attribute['attributes']['statusCode'],
actionType: actionType_code,
),
);
},
);
This is an example of a JSON file I get from the API.
{
"data": [
{
"id": "17db1506f6d-3ca8",
"type": "wo",
"links": {
"self": "https://API_URL/wo/17db1506f6d-3ca8",
"workflow-transitions": "https://API_URL/wo/17db1506f6d-3ca8/workflow-transitions"
},
"attributes": {
"description": "test",
"code": "TEST",
"statusCode": "REQUEST"
},
"relationships": {
"actionType": {
"links": {
"self": "https://API_URL/wo/17db1506f6d-3ca8/relationships/actionType",
"related": "https://API_URL/wo/17db1506f6d-3ca8/actionType"
}
},
"assignedTo": {
"links": {
"self": "https://API_URL/wo/17db1506f6d-3ca8/relationships/assignedTo",
"related": "https://API_URL/wo/17db1506f6d-3ca8/assignedTo"
}
}
}
},
]
}
I hope that someone can help me to solve this problem.

Flutter Amplify Cognito, no tokens using fetchAuthSession

I'm trying to implement authentication in my Flutter app using Cognito. I'm authenticating against an existing userPool which I've been successfully using for the past year in my React app.
However, with Flutter I'm not able to fetch the user's session. I'm able to login successfully but I'm unable to get any tokens using the fetchAuthSession() method. Any idea why this is happening? Here is some of my working and non-working code:
This code is successful...
Future _usersEmail() async {
try {
var attributes = (await Amplify.Auth.fetchUserAttributes()).toList();
for (var attribute in attributes) {
if (attribute.userAttributeKey == 'email') {
print("user's email is ${attribute.value}");
return '${attribute.value}';
}
}
return 'no email';
} on AuthException catch (e) {
return '${e.message}';
}
}
This code is successful too...
Future<bool> _isSignedIn() async {
final CognitoAuthSession session =
await Amplify.Auth.fetchAuthSession() as CognitoAuthSession;
print('_isSignedIn: ${session.isSignedIn}');
return session.isSignedIn;
}
This code return null...
Future _getIdToken() async {
final CognitoAuthSession session =
await Amplify.Auth.fetchAuthSession() as CognitoAuthSession;
final idToken = session.userPoolTokens?.idToken;
print('idToken: $idToken');
return idToken;
}
Here is my amplifyconfig...
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"UserAgent": "aws-amplify-cli/0.1.0",
"Version": "0.1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "us-east-1_abcxyz",
"Region": "us-east-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-1_abcxyz",
"AppClientId": "5j0kii90dJ09est43xh3X21",
"Region": "us-east-1"
}
},
"Auth": {
"Default": {
"authenticationFlowType": "USER_SRP_AUTH"
}
}
}
}
}
}
you might need to set getAWSCredentials to true in your options parameter like so:
final authSession = (await Amplify.Auth.fetchAuthSession(
options: CognitoSessionOptions(getAWSCredentials: true),
)) as CognitoAuthSession;

How to handle errors via Ferry GraphQL

community!
Please give a clue how to handle GraphQL errors by Ferry.
To simplify let's say that I have toLogin function:
await toLogin(_email, _password);
and it initiates login procedure:
Future<void> sendLogin(String _email, String _password) async {
final _sendLoginRequest = GLoginReq((b) => b
..vars.identifier = _email
..vars.password = _password);
final _client = initClient();
final _storage = GetStorage();
_client.request(_sendLoginRequest).listen((response) {
if (response.hasErrors) {
print('error');
} else {
print('success');
}
});
}
Works fine but I need to add error handling at the main program.
so I add
String _result = await toLogin(_email, _password);
to the main and return to the toLogin();
Future<String> sendLogin(String _email, String _password) async {
final _sendLoginRequest = GLoginReq((b) => b
..vars.identifier = _email
..vars.password = _password);
final _client = initClient();
String _result = 'init';
_client.request(_sendLoginRequest).listen((response) {
if (response.hasErrors) {
print('error');
_result = 'error';
} else {
print('success');
_result = 'success';
}
});
return _result;
}
The problem is that it returns _result before any check and Dart do not allow me to use await
OK, let's try another way:
var _response = OperationResponse(
operationRequest: _sendLoginRequest,
);
var _checkErrors = _response.graphqlErrors;
print(_checkErrors);
But it's always false
I've found option graphqlErrors at OperationResponse but do not have any idea what to fill there.
Please give me a clue how to handle it.
I use Strapi as the backend, the error example is as follows:
{
"errors": [
{
"message": "Bad Request",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"login"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"code": 400,
"data": {
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"messages": [
{
"id": "Auth.form.error.invalid",
"message": "Identifier or password invalid."
}
]
}
],
"data": [
{
"messages": [
{
"id": "Auth.form.error.invalid",
"message": "Identifier or password invalid."
}
]
}
]
},
"stacktrace": [
"Error: Bad Request",
" at checkBadRequest (C:\\Projects\\Zhugory\\zhugory-strapi-graphql\\zhugory-strapi\\node_modules\\strapi-plugin-users-permissions\\config\\schema.graphql.js:13:23)",
" at resolver (C:\\Projects\\Zhugory\\zhugory-strapi-graphql\\zhugory-strapi\\node_modules\\strapi-plugin-users-permissions\\config\\schema.graphql.js:217:11)",
" at runMicrotasks (<anonymous>)",
" at processTicksAndRejections (internal/process/task_queues.js:93:5)"
]
}
}
}
],
"data": null
}

How do you parse JSON that is inside an array

I am new to flutter development and is experimenting with how to use the flutter HTTP package 0.12.0+2.
If the response looks like this...
{
"coord": {
"lon": -76.8403,
"lat": 38.9649
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 93.47,
"feels_like": 99.34,
"temp_min": 88.84,
"temp_max": 97.74,
"pressure": 1017,
"humidity": 46
},
"visibility": 10000,
"wind": {
"speed": 1.99,
"deg": 304,
"gust": 1.99
},
"clouds": {
"all": 1
},
"dt": 1626462013,
"sys": {
"type": 2,
"id": 2030617,
"country": "US",
"sunrise": 1626429293,
"sunset": 1626481895
},
"timezone": -14400,
"id": 4369076,
"name": "Seabrook",
"cod": 200
}
Here is the code I have. Instead of printing all the data, how do I print only temp inside main
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data);
}
You can use:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); //Will return [temp], [feels_like], [temp_min], etc..
print(data['main']['temp']); //Will return [93.47]
}
You can access the values of each fields by using the operator [$field] on the decoded json. Something like this:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude=.{part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); // prints out { temp: 93.47, ...., humidity: 46 }
// what you want..
final mainTemp = data['main']['temp'];
print(mainTemp); // prints out 93.47.
print(data);
}
So, that's how you access the fields of of the decoded json-string response.
If you plan to use these received values throughout your app, consider changing the received response into an Interface which will provide you with more flexibility and also makes your code look cleaner.
Create Model Class here you can convert json to dart
https://javiercbk.github.io/json_to_dart/
Future<YourmodelName>getData() async {
YourmodelName data
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?
lat=38.964882&lon=-76.840271&exclude=
{part}&appid=b29e187fed23cf37dc160e6c115a270d');
if (response.statusCode == 200) {
data = YourmodelName.fromJson(response.data);;
print(data.main.temp);}
return data;
}

Azure Machine Learning REST API: no body

I am simply strying to call the REST API end point of a machine learning experiment created with Azure. I keep getting this error message:
{
"error": {
"code": "BadArgument",
"message": "Invalid argument provided.",
"details": [
{
"code": "RequestBodyInvalid",
"message": "No request body provided or error in deserializing the request body."
}
]
}
}
I have looked it up on their documentation: https://learn.microsoft.com/en-us/azure/machine-learning/machine-learning-web-service-error-codes
All it says is that my bod is empty, I am not sure how can it be empty, here is my code:
router.post('/rating/new', function(req, res) {
var postData = {
"Inputs": {
"input2":
[
{
'Col1': "A11",
'Col2': "6",
'Col3': "A34",
'Col4': "A43",
'Col5': "1169",
'Col6': "A65",
'Col7': "A75",
'Col8': "4",
'Col9': "A93",
'Col10': "A101",
'Col11': "4",
'Col12': "A121",
'Col13': "67",
'Col14': "A143",
'Col15': "A152",
'Col16': "2",
'Col17': "A173",
'Col18': "1",
'Col19': "A192",
'Col20': "A201",
'Col21': "1",
}
],
},
"GlobalParameters": {
}
};
// Configure the request
var options = {
url: config.ML_PREDICTIVE.url,
method: 'POST',
headers: {
'Content-Type':'application/json',
'Authorization':('Bearer ' + config.ML_PREDICTIVE.apiKey)},
form: postData
}
console.log(JSON.stringify(options));
// Start the request
request.post(options, function (error, response, body) {
if(error){
res.status(403).send(error);
}
if(response.statusCode != 200){
res.status(403).send(response.body);
}
if (!error && response.statusCode == 200) {
console.log(body)
}
})
});
The only thing I see that could go wrong is that "form" in the request is not considered body by azure, I have tried with "body" as well no success.
Please help !
According to the code you provided, the variable postData is not valid JSON string. You'd need to use JSON.stringify() method to convert postData value to a JSON string before you send a POST request.