Setting User-Agent request header in Cordova app - javascript

I am building a Cordova-based app in Typescript and I need to send an HTTP GET request to a NTRIP Caster. Though a fairly simple procedure, the NTRIP Caster requires that the User-Agent request header be set to "NTRIP (something)" or it will reject the request.
Unfortunately, it seems I cannot change the header via a simple XMLHttpRequest without getting a Refused to set unsafe header "User-Agent" error due to browser restrictions. I've also tried Angular's $http.get and even jQuery, with no luck.
What are my alternatives? Is there a cordova plugin I should be using, or some library/wrapper I can use?
I am very new to Cordova and JS in general so bear with me -- I might follow up with some inane questions.

Found the answer here: How i can set User Agent in Cordova App
Basically, set the following in config.xml:
preference name="OverrideUserAgent" value= "NTRIP/whatever" />
Alternatively, I found this Cordova plugin that claims to do the same, but I haven't tested it:
https://github.com/LouisT/cordova-useragent

Related

Cordova InAppBrowser executeScript callback

I try to parse some site and execute script in Cordova InAppBrowser's method executeScript on iOS and return some result in callback function, but get this error:
Refused to load gap-iab://InAppBrowser1249228873/%5Bnull%5D because it does not appear in the frame-src directive of the Content Security Policy.
I understand, that gap-iab:// scheme should be included to Content Security Policy in <meta> tag, but code is executing not on my site and I don't have access to it.
Can anyone suggest a decision to resolve this problem?
P.S. On Android executeScript works perfectly.
You could use nginx to proxy the HTML page you are trying to load. You'd set up nginx to proxy the site you are loading in the InAppBrowser, and use the add-header to add a Content-Security-Policy in the response with "'default-src' gap: gap-iab:"
The one issue you may have is if the original server already includes a strict Content-Security-Policy, because the strictest content-security-policy will get applied.

how to garmin login using javascript

Im trying to implement an Oauth1 login to garmins using Angular2 and regular http calls, but on the first call to oauth/request_token path i get a pre-flight OPTIONS call error seems not having CORS enabled or something.
It may anyone tried or did this before?
Thanks
You have to set Origin in your header (my suggestion is to do it with an interceptor) and then in your server config allow your domain or localhost:port to access it.

Can not read Set-Cookie header in Cordova based App

I'm trying to read the Set-Cookie header in Cordova based application, but looks like is blocked by iOS 9 . I have tried using Access-Control-Allow-Credentials / Access-Control-Expose-Headers without luck.
I read getResponseHeader() will return null for Set-Cookie/Set-Cookie2.
Also i know that cookie support was never stated by Cordova/Phonegap.
I'm using Cordova v5.0.0 and iOS v9.3.1.
I'm interested in read the Set-Cookie header and not in the store it. I'm looking for a workaround to prevent backend team have to implement a Token based authentication.
https://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
cookie support in cordova official documentation
First of all, the latest cordova version is 6.x
Second, I advvice you to use this JS API for handling cookies ( https://github.com/js-cookie/js-cookie ) it's really easy to use and I haven't really encountered any problems with it at all.
Example:
Create a cookie, valid across the entire site:
Cookies.set('name', 'value');
Read cookie:
Cookies.get('name'); // => 'value'

Cross domain Ajax JSON POST support against RESTful WCF service using transportCredentialOnly security

I've posted before on this subject, but after a year of getting on with other things, I've managed to get into a pickle once again. I'll try and give a brief overview of the scenario and the current attempts to make things work:
IIS web server hosting HTML, JS etc. on host: iis.mycompany.com (referred to as foo)
WCF RESTful web services hosted via a Windows Service on host: wcf.mycompany.com (referred to as bar)
The Javascript served from foo works by making RESTful ajax calls (GET or POST depending on the action) to the WCF services on bar, obviously these are cross domain calls as they aren't on the same host.
The Javascript uses the jQuery (1.7.2) framework to manipulate the DOM and perform ajax calls to bar, the expected content type for POSTS is JSON, and the response from GETS is expected to be JSON too (application/json).
Bar has it's WCF services configured using TransportCredentialOnly as the security mode and the transport client credentail type is NTLM, so only authed users to contact the services.
CORS Support has been added to bar's WCF services using an extension to WCF:
http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx
We have added additional headers and modfied some that the post already contained based on numerous internet articles:
property.Headers.Add("Access-Control-Allow-Headers", "Accept, Content-Type");
property.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
property.Headers.Add("Access-Control-Max-Age", "172800");
property.Headers.Add("Access-Control-Allow-Origin", "http://iis.mycompany.com");
property.Headers.Add("Access-Control-Allow-Credentials", "true");
property.Headers.Add("Content-type", "application/json");
Sites giving information on enabling CORS suggest that the Access-Control-Allow-Origin response header should be set to "*" however, this is not possible in our case as we make jQuery ajax calls using the following setup:
$.ajaxSetup({
cache: "false",
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
As it turns out you cannot use "*" for the accepted origin when you are using "withCredentials" in the ajax call:
https://developer.mozilla.org/en/http_access_control
"Important note: when responding to a credentialed request, server
must specify a domain, and cannot use wild carding."
Currently in our development lab, this doesn't matter as we can hard code the requests to the IIS (foo) server URL.
The main problem now appears to be attempting POST requests (GET is working using the above configuration). When the browser attempts the POST process, it first sends an OPTIONS header to the server requesting allowed OPTIONS for the subsequent post. This is where we would like to see the headers we've configured in the CORS Support WCF extension being passed back, however we aren't getting that far; before the response comes back as "401 Unauthorized", I believe this is to do with the transport security binding configuration requesting NTLM, but I'm not sure.
Also, I'm not very experienced with this, but I haven't seen much information about POST using application/json content type as opposed to text/plain when performing cross domain requests.
I know that people will probably suggest JSONP as the one true solution, I'm not against different approaches, indeed I encourage anyone to suggest best practices as it would help others reading this question later. However, please attempt to answer the question before suggestion alternatives to it.
Many thanks in advance for anyone who contributes.
peteski
:)
UPDATE:
It appears that Chrome (20.x.x) doesn't suffer the problem of not negotiating NTLM to retrieve the OPTIONS header response from the server, but Firefox (13.0.1) does.
We've also noticed that someone has already posted a bug up on the Firefox forum, which we've added information to:
http://bugzilla.mozilla.org/show_bug.cgi?id=751552
Please vote for this bug to be fixed on the bugzilla site!
Using the following code, we can watch the network trace to see Firefox failing and Chrome working fine:
var url = "http://myWebServiceServer/InstantMessagingService/chat/message/send";
var data = '{ "remoteUserUri" : "sip:foo.bar#mydomain.com", "message" : "This is my message" }';
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.withCredentials = true;
request.setRequestHeader("Content-Type", "application/json");
request.send(data);
console.log(request);
On a separate note, IE8 doesn't support the XMLHttpRequest for cross domain calls, favouring it's own magical XDomainRequest object, so we've got some work to do in changing the client side code to handle IE8 vs the world cases. (Thanks IE8).
/me crosses fingers that Mozilla fix the Firefox bug.
UPDATE 2:
After some digging it appears that IE8's XDomainRequest cannot be used to make cross domain requests where NTLM must be negotiated, this basically means that the security on our WCF binding can't be used thanks to limitations in a web browser.
http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
"No authentication or cookies will be sent with the request"
So, I guess we've taken this as far as it is going to go for now.. It looks like we're going to have to create our own custom token authentication and pass it across to the WCF service in a cookie, or in IE8's case, POST it with the JSON. The WCF service will then have to handle decrypting the data and using that instead of the ServiceSecurityContext.Current.WindowsIdentity we previously had access to with NTLM auth.
I know you said you would rather have the problem itself addressed, but you may consider using a "reverse proxy."
I don't know what technologies you are using, but we use Apache web server and have a Java RESTful API running on a different server that required authentication. For a while, we messed with JSONP and CORS, but were not satisfied.
In the end, we setup an Apache Reverse Proxy and it worked miracles. The web browser believes it is communicating with its own domain and acts appropriately. The RESTful API doesn't know it is being used via a proxy. Therefore, everything just works. And Apache does all the magic.
Hopefully, all web servers have a feature like Apache's reverse proxy.
Here is some documentation on the feature: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
All we had to do is ensure the mod_proxy module was installed, then add the following lines to our Apache config file:
ProxyPass /restapi http://restfulserver.com/restapi
ProxyPassReverse /restapi http://restfulserver.com/restapi
Then restart the web server and voila!

secure xmlhttprequest from nonsecure page

I want to make an XMLHttpRequest to a secure uri (https://site.com/ajaxservice/) from javascript running inside a nonsecure page (http://site.com/page.htm). I've tried all kinds of nutty stuff like iframes and dynamic script elements, so far no go. I know I am violating 'same origin policy' but there must be some way to make this work.
I will take any kind of wacky solution short of having the SSL protocol written in javascript.
That won't work by default due to the same origin policy, as you mentioned. Modern browsers are implementing CORS (Cross-Origin Resource Sharing) which you could use to get around this problem. However this will only work in Internet Explorer 8+, Firefox 3.5+, Safari 4+, and Chrome, and requires some server-side work. You may want to check out the following article for further reading on this topic:
Cross-domain Ajax with Cross-Origin Resource Sharing by Nicholas C. Zakas
You can also use JSONP as Dan Beam suggested in another answer. It requires some extra JavaScript work, and you may need to "pad" your web service response, but it's another option which works in all current browsers.
You can't circumvent cross-domain origin with XHR (well, only in Firefox 3.5 with user's permission, not a good solution). Technically, moving from port 80 (http) to 443 (https) is breaking that policy (must be same domain and port). This is the example the specification itself sites here - http://www.w3.org/Security/wiki/Same_Origin_Policy#General_Principles.
Have you looked into JSONP (http://en.wikipedia.org/wiki/JSON#JSONP) or CSSHttpRequests (http://nb.io/hacks/csshttprequest)?
JSONP is a way to add a <script> tag to a page with a pre-defined global callback across domains (as you can put the <script>s src to anywhere on the web). Example:
<script>
function globalCallback (a) { /* do stuff with a */ }
And then you insert a <script> tag to your other domain, like so:
var jsonp = document.createElement('script');
json.setAttribute('src','http://path.to/my/script');
document.body.appendChild(jsonp);
</script>
And in the source of the external script, you must call the globalCallback function with the data you want to pass to it, like this:
globalCallback({"big":{"phat":"object"}});
And you'll get the data you want after that script executes!
CSSHttpRequests is a bit more of a hack, so I've never had the need to use it, though feel free to give it a try if you don't like JSONP, :).
You said you would take anything short of having the SSL protocol written in JavaScript... but I assume you meant if you had to write it yourself.
The opensource Forge project provides a JavaScript TLS implementation, along with some Flash to handle cross-domain requests:
http://github.com/digitalbazaar/forge/blob/master/README
Check out the blog posts at the end of the README to get a more in-depth explanation of how it works.

Categories