here is an Android mobile application , from which I'm making call to SAP SERVER .I came across a very strange problem.
I'm making a ajax call to server and getting data as expected.
but the problem is getResponseHeader is coming empty. But I can see the response header in browser console and it is as per my expectation.
How to get the response header?
Browser Console image
var a = {};
a = {
// object that contains HTTP headers as name value pairs
"Authorization" : "Basic " + btoa(username + ":" + password),
"X-CSRF-Token" : "Fetch",
},
$.ajax({
type: "GET",
cache: false,
url: requestUri1,
headers: a,
success: function(a, b, c) {
globalTocken = c.getResponseHeader("X-CSRF-Token");
alert(globalTocken);
},
statusCode: {
401: function() {
alert("User name and password is wrong");
},
403: function() {
alert("error 403");
}
},
error: function(a, b) {
alert(b);
}
});
I have tried these ways also.
OData.request ({
requestUri: requestUri1,
method: "GET",
headers: {
"Authorization" : "Basic " + btoa(user_name + ":" + pass_word),
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/atom+xml",
"DataServiceVersion": "2.0",
"X-CSRF-Token":"Fetch"
}
},
function (data, response)
{
var header_xcsrf_token = response.headers['x-csrf-token'];
//console.log(header_xcsrf_token);
alert(header_xcsrf_token);
},function(err) {
//Error Callback:
alert("Error occurred " + err.message + err.response.statusText);
});
Another way
var request = {
headers : {
// object that contains HTTP headers as name value pairs
"Authorization" : "Basic " + btoa(user_name + ":" + pass_word),
"X-CSRF-Token" : "Fetch",
},
requestUri : requestUri1, // OData endpoint URI
method : "GET",
datatype : "json",
};
OData
.read(
request,
function(data,response) {
x_csrf_token = response.headers["X-CSRF-Token"];
}, function(err) {
//Error Callback:
alert("Error occurred " + err.message + err.response.statusText);
});
}
I have done lot of R&D and reached to a conclusion that all of the three coding are correct problem is from server side, it is not generating Token everytime so I have saved token in local memory and using it until the new one will not get generate from server(I'm making call to server everytime). it is working for me.
function save_all(){
var globalTocken,X_CSRF_Token,a = {};
a.Authorization = "Basic " + btoa("username" + ":" + "password"),
a["X-CSRF-Token"] = "fetch",
$.ajax({
type: "get",
cache: !1,
url: requestUri1,
headers: a,
dataType: "xml",
success: function(a, b, c) {
if(!c.getResponseHeader("X-CSRF-Token")){
globalTocken = localStorage.savedTocken;
X_CSRF_Token = globalTocken;
else{
globalTocken = c.getResponseHeader("X-CSRF-Token");
localStorage.removeItem("savedTocken");
localStorage.setItem("savedTocken",globalTocken);
X_CSRF_Token = globalTocken;
}
},
statusCode: {
401: function() {
alert("User name and password is wrong");
},
403: function() {
alert("error 403");
}
},
error: function(a, b) {
alert(b);
}
});
Related
I am new to typescript and trying to upload an image from my mobile SD card. I am getting the image path when browsing the image. And when I pass this along with the form data None is returning. It would be great if someone give a helping hand to figure out the issue.
I am using "nativescript-imagepicker" library for getting image from SD Card..
sendPicture(uri: string, modelContext: any){
let _formData = new FormData();
_formData.append("profile_image", uri);
let body = _formData;
updateAvatarService(this.userToken,body).subscribe(data => {
});
}
updateAvatarService(token,body): Observable<any> {
return this.httpClass.patchMethodWithToken(URL,token,body)
.map(response => {
return response;
})
}
patchMethodWithToken(url: string, token: string, data: Object ) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', "Token " + token);
headers.append('Content-Disposition', "form-data");
let options = new RequestOptions({ headers: headers });
if (this.checkNetworkConnection()) {
return this.http
.patch(url, JSON.stringify(data), options)
.map(response => {
return response.json();
})
.catch(this.handleErrors);
}
}
For multipart upload as form data I was using Nativescript-background-Http
Below is the sample implementation and it is working for me -
import { session, Session, Task } from "nativescript-background-http";
var session1 = session("image-upload");
uploadImage(fileUri, id) {
let imageName = this.extractImageName(fileUri);
let headers = new Headers();
headers.append("Authorization", Config.token);
headers.append("CenterId", Config.CenterId);
var options = new RequestOptions({ headers: headers });
var request = {
url: Config.putImage + id + "/upload",
method: "POST",
headers: {
"Authorization": Config.token,
"X-Center-Id": Config.XCenterId,
"Content-Type": "application/octet-stream",
"File-Name": imageName
},
description: "{ 'uploading': " + imageName + " }"
};
var params = [{ name: "image", filename: fileUri, mimeType: 'image/jpeg' }];
var task = session1.multipartUpload(params, request);
task.on("progress", logEvent);
task.on("error", logEvent);
task.on("complete", logEvent);
function logEvent(e) {
console.log(".........................")
console.log("currentBytes: " + e.currentBytes);
console.log(".........................")
console.log("totalBytes: " + e.totalBytes);
console.log(".........................")
}
return task;
}
//Extract file Name
extractImageName(fileUri) {
var pattern = /[^/]*$/;
var imageName = fileUri.match(pattern);
return imageName;
}
I try to create Cordova mobile app based on angularjs following this tutorial: https://mobilefirstplatform.ibmcloud.com/blog/2016/08/11/best-practices-for-building-angularjs-apps-with-mobilefirst-foundation-8.0/
and LTPA Based Security Check login flow (in Mobilefirst 8.0) based on sample from: https://github.com/mfpdev/ldap-and-ltpa-sample
Mobile app is using angular. Authorisation implementation:
app.factory('Auth', function ($rootScope) {
var securityCheckName = 'LTPA',
_$scope = null,
challengeHandler = null,
URL = '',
challengeHandler = WL.Client.createSecurityCheckChallengeHandler(securityCheckName);
challengeHandler.securityCheckName = securityCheckName;
WLAuthorizationManager.login(securityCheckName, {'username': '', 'password': ''});
challengeHandler.handleChallenge = function (challenge) {
if (challenge && challenge.loginURL) {
URL = challenge.loginURL;
}
};
challengeHandler.handleSuccess = function (data) {
// code
};
challengeHandler.handleFailure = function (error) {
// code
};
return {
login: function ($scope, username, password) {
_$scope = $scope;
var request = new WLResourceRequest(URL, WLResourceRequest.POST);
request.send("j_username=" + username + "&j_password=" + password + "&action=Login").then(
function(response) {
challengeHandler.submitChallengeAnswer({});
},
function(error) {
// on error
});
}
};
});
This seems to work only on iOS. On Android handleSuccess function is not invoked.
As in the past, there was a problem with sending cookies on Android devices (with older MF versions) so I tried workaround in login function, that the hidden InAppBrowser was opened with logon form, then a user login process was made and once token was received, it was set via cordova-cookie-master-plugin and submitChallengeAnswer was invoked:
login: function ($scope, username, password) {
_$scope = $scope;
var request = new WLResourceRequest(URL, WLResourceRequest.POST);
request.send("j_username=" + username + "&j_password=" + password + "&action=Login").then(
function(response) {
if (device.platform == "iOS") {
challengeHandler.submitChallengeAnswer({});
} else {
iab = cordova.InAppBrowser.open(URL, "_blank", "hidden=yes");
iab.addEventListener('loadstop', function(event){
iab.executeScript({code:
'var field1 = document.getElementsByTagName("input")[0];' +
'var field2 = document.getElementsByTagName("input")[1];' +
'field1.setAttribute("value", "' + username + '");' +
'field2.setAttribute("value", "' + password + '");' +
'document.forms[0].submit();'
}, function(){
// on error
});
try {
cookieMaster.getCookieValue(URL, 'LtpaToken2', function(data) {
WL.Client.setCookie({
"name" : "LtpaToken2",
"value" : data.cookieValue,
"domain" : ".example.com",
"path" : "/",
"expires" : "Thu, 18 Dec 2999 12:00:00 UTC"
}).then(function() {
challengeHandler.submitChallengeAnswer({});
}).fail(function(err) {
// on error
});
}, function(error) {
// on error
});
} catch(err) {
// on error
}
});
iab.addEventListener('exit', function(){
iab.removeEventListener('loadstop', function() { /* on success */ });
});
}
},
function(error) {
// on error
});
}
This solution also not working for me. I've expect that after challengeHandler.submitChallengeAnswer() was fired, the handleSuccess will be invoked, but it is not happened. handleChallenge is invoked instead.
i developed an App with cordova that communicates with a WebService. It works with Ios, but if I try to use it with Android, at first WebService calling, it doesn't work...
here my code:
doLogin: function (user, password, successCallback, failCallback) {
jApp.gui.showWait();
var parametri = "NomeUtente=" + user + "&Password=" + password;
$.ajax({
url: serviceUrl + "Login.ashx?" + parametri,
dataType: "jsonp",
dataFilter: null,
async: true,
success: <-- I think it stops here
function (r) {
jApp.gui.hideWait();
if (r.Success)
{
//salvo le credenziali su file
var strLogin = '{"user":"' + user + '","password":"' + password + '"}';
window.resolveLocalFileSystemURL(pathApp, function (dir) {
dir.getFile("login.json", {create: true}, function (file) {
file.createWriter(function (fileWriter) {
fileWriter.seek(fileWriter.length);
var blob = new Blob([strLogin], { type: 'text/plain' });
fileWriter.onwriteend = function (evt) {
successCallback(r);
}
fileWriter.write(blob);
}, failCallback);
});
});
//TODO: salvarsi user e pwd?
}
else
{
alert(r.ErrorMessage);
}
},
error: function (e) {
jApp.gui.hideWait();
alert("errore");
}
});
Thank you
I am developing an android app using apache cordova tools in visual studio 2015. I want to call a web service from my index page in cordova app, but I somehow can't achieve it.
Here is the HTML
<div ><input type="button" id="callwebmethod" name="submit" /> <br /> </div>
Here is the JS function
<script type="text/javascript">
$('#callwebmethod').click(function () {
var params = "{'msg':'From Client'}";
$.ajax({
type: "POST",
url: "http://mysite/index.aspx/GetEmployees",
data: params,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) { alert(result.d); }
});
})
</script>
Here is the web method
[WebMethod]
public static string GetEmployees()
{
return "Hello World";
}
Your var params have to be simular to the Parameters of the WebMethod. Just leave them empty and try it again. They have to be exactly the same.
If you whant to use web methods with parametes here is a working example:
$.ajax({
url: "http://systemservice/systemservice.asmx/App_Test",
data: "{ par1: '" + xxx + "', par2: '" + xxx + "'}",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.d) {
//Do something
}
},
error: function (xhr) {
alert("An error occured: " + xhr.status + " " + xhr.statusText);
}
})
[WebMethod]
public string App_Test(string par1, string par2) {
return "Hello";
}
With the shown error function you can also find out what is going wrong.
To do it without the paremeters you just have to leave them empty.
data: "{}"
[WebMethod]
public string App_Test() {
return "Hello";
}
It woked for me this example:
var person = {};
person.ID = $('#txtID').val();
person.Name = "Amir";
var pdata = { "p": person };
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/SampleService.asmx/GetPesonnelSalary",
data: JSON.stringify(pdata),
dataType: "json",
async: true,
success: function (data, textStatus) {
if (textStatus == "success") {
if (data.hasOwnProperty('d')) {
msg = data.d;
} else {
msg = data;
}
alert(msg);
}
},
error: function (data, status, error) {
alert("error");
}
});
The complete code is here: http://www.scriptiny.com/2012/12/calling-asmx-web-service-via-jquery-ajax-2/
We have encountered a strange problem in the payment module of trigger.io. The flow works perfectly with ios payments but in android, some in-app payment callbacks are called twice in the same second. the receipt signatures are different but the orderid, notificationid, purchasetoken and developerPayload all stay the same. when we try to validate the receipt it turns out to be true and correct. But when we look at the financial report, we only see one payment instead of two (because its probably just one payment but why the different signatures?).
why is trigger.io calling the callback twice which leads to the product being bought twice? why is android returning 2 different and confirmable receipts for one payment? is this a bug on andorid side or trigger.io side, cause i have no way of calling the callback using javascipt? or is this a known hack attempt?
We also encountered a case where no callback was called at all, whereas the credit card was charged successfully. Is this a bug or are there any workarounds for this case?
here is the code i'm initiating a purchase:
if(forge.is.android())
forge.payments.purchaseProduct("someproductname", paymentSuccess, paymentError);
and here is the callback function:
function paymentCallback(data, confirm){
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:"function=logPayment&action=PaymentCallbackStart",
success: function (data) {
hideLoader();
},
error: function (error) {
hideLoader();
}
});
var productId = data.productId;
var orderId = data.orderId;
var signed_data;
if(forge.is.android())
{
var state = data.purchaseState;
var receipt = encodeURIComponent(data.receipt.signature);
signed_data = encodeURIComponent(data.receipt.data);
}
else if(forge.is.ios())
{
var state = data.PurchaseState;
var receipt = data.receipt.data;
}
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:"function=logPayment&data=" + encodeURIComponent("birthday=" + gbirthday + "&birthhour=" + gbirthhour + "&name=" + gname + "&gender=" + ggender + "&birthday2=" + gbirthday2 + "&birthhour2=" + gbirthhour2 + "&name2=" + gname2 + "&gender2=" + ggender2 + "&content=" + text + "&ProductID=" + qs.ProductID + "&userId=" + guserId + "&data=" + JSON.stringify(data)) + "&action=PaymentCallback",
success: function (data) {
hideLoader();
},
error: function (error) {
hideLoader();
}
});
if(state == "PURCHASED")
{
if(typeof gbirthday != "undefined")
{
var text = $('#imessagem').val();
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:"function=askQuestion&birthday=" + encodeURIComponent(gbirthday) + "&birthhour=" + encodeURIComponent(gbirthhour) + "&name=" + encodeURIComponent(gname) + "&gender=" + ggender + "&birthday2=" + encodeURIComponent(gbirthday2) + "&birthhour2=" + encodeURIComponent(gbirthhour2) + "&name2=" + encodeURIComponent(gname2) + "&gender2=" + ggender2 + "&content=" + encodeURIComponent(text) + "&ProductID=" + qs.ProductID + "&userId=" + guserId + "&signed_data=" + signed_data + "&receipt=" + receipt,
success: function (data) {
processPayment(productId,orderId)
hideLoader();
},
error: function (error) {
hideLoader();
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:"function=logPayment&data=" + encodeURIComponent(JSON.stringify(error)) + "&action=PaymentQuestionError",
success: function (data) {
hideLoader();
},
error: function (error) {
hideLoader();
}
});
}
});
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:"function=logPayment&data=" + encodeURIComponent(JSON.stringify(data)) + "&action=Payment",
success: function (data) {
hideLoader(); },
error: function (error) {
hideLoader();
}
});
}
if(forge.is.android())
processPayment(productId,orderId);
}
else
{
if(forge.is.ios())
processPayment(productId,orderId);
}
confirm();
}
This is called a replay attack. Normally you will update your database if you have received a payment(callback, eg. IPN for PayPal). If they call the same order again and again the attack will fail because the status is already set to true.
In earlier days this was a common attack.
Read following articles:
http://en.wikipedia.org/wiki/Replay_attack
How do I prevent replay attacks?
Edit: I guess you do an insert in your database after the callback? It is better to insert the order before the callback(before the actual checkout) and create a status field in your table which is set default to false. When the callback is succeeded you must update the status and set it to true.
Eg. I want to order a pizza(owner puts my order in the system). My receipt is my proof of payment(callback). When the pizza is ready I eat it but I'm still hungry. I go back to the pizzaboy and I ask for a new one(I could repeat this a thousand times). A simple solution would be to destroy my receipt or put a signature on it(update status) and I wouldn't be able to order the same pizza all over again.
Edit edit: When you accept PayPal be aware of the chargeback 'attack'(http://forums.whirlpool.net.au/archive/2214159).
13/05/2014 : The only thing I see at the moment is that your AJAX data property is formatted wrong. This isn't a string but an object. The isn't probably the real problem. If you not always receive a callback and you are sure that your request hits the Google servers I guess it is a problem on their side(or Trigger.IO). I would advice you to contact Trigger.IO to make sure that your request actually hits their servers. If it does, you could contact Google about this problem and see if they receive all of your requests.
forge.request.ajax({
url: "someurl.php",
dataType: "json",
data:{
function(watchOut!! 'function' is a reserved keyword!!) : 'logPayment',
action : 'PaymentCallbackStart'
},
success: function (data) {
hideLoader();
},
error: function (error) {
hideLoader();
}
});