First, let me start with, I understand JavaScript can be tampered with so I'm not looking for a fool-proof solution. I have a public API that takes requests from external web applications. Sometimes the web applications are directly hitting our API and other times they jump through another API offered by some of our Partners.
In a partner scenario, we want to ensure the API requests are ultimately coming from specific URLs. My idea is this:
We're allowed to offer a script that the webapps can add to their sites so I was thinking we can set up an API Endpoint whose job is to capture the request, verify the origin (URL), and spit out a token that they must ultimately send later with the real API request through the partner API.
Is there a better approach or am I just really limited to the origin header to find out the website? I was hoping there were additional data points I can leverage on the client side to verify the traffic is coming from a specific URL
I've trying several things but nothing is really working. There are some examples in Vuforia Web Services API documentation using PHP but there's nothing with JavaScript.
It seems there's no Javascript API available for VWS. Even if it were, you will probably not be able to call it from web browser because of Cross domain policies.
That said, you can write your own back-end client in JS or run one of the samples in (Java/PHP/Python) in the server and expose all the methods as REST end-points.
VWS seems to be plain old REST services, which can be called from any language.
Only hurdle in writing your own simple client is to calculate signature for the requests, here's the logic to calculate signature from the documenation
Ref: https://library.vuforia.com/content/vuforia-library/en/articles/Training/Using-the-VWS-API.html
After you have the function for signature you will have to convert sample requests from the download for selected language to Javascript
These are the files in sample that I downloaded for Java, (https://github.com/christolb/MobEmbedded/tree/master/Pradeep/VWS%20Sample, it's uploaded by someone else on Github, I'm not adding it here myself, as I'm unsure of the licensing restrictions)
DeleteTarget.java
GetAllTargets.java
GetTarget.java
PostNewTarget.java
SignatureBuilder.java
Summary.java
TargetState.java
TargetStatusListener.java
TargetStatusPoller.java
UpdateTarget.java
Thinking about HTTPS, it is a compute-intensive protocol and one should only use it where necessary. I'm working on a web application and I will be using Angular.js MVC on the client side, calling into WebAPI REST Api returning JSON.
When I think about it I do not need to encrypt the HTML, the client-side javascript or styles sheet etc. After initial handshake only the data calls to the REST Api need encrypting.
Do other people do this? Are there any pitfalls or caveats?
Here's a great Mozilla article detailing their restrictions and why they exist.
Their recommendation is to always stick strictly to either HTTP or HTTPS.
Also, I suspect that browsers and web servers will greatly minimize the impact of encrypting the data over ssl on subsequent calls. I suspect if you profile it you'll find the impact minimal/non-measurable.
I'm currently working on a small JavaScript library which makes requests to a REST web service. Since the server side needs to log incoming request to measure the number of requests, I want to secure it somehow. The library is very similar to the Google Maps API. So my question is now, is there some way to secure it better then just adding an API key to the libraries requests? How can I ensure, if that is even possible, that only the 'right' client uses the key? I guess I could compare the referrer url to a set of valid urls, but this can be spoofed to right? Please keep in mind that is impossible to use some else's authentication method (facebook, google, twitter etc.) since it has to work without user input.
Cheers,
Daniel
A decent RESTful approach would be to require an Authorization header to be supplied by the client, matching some scheme that your server will accept (see Basic Access authentication as an example). Seeing as you only wish to validate that your client is the one making the request, you probably don't need too complex an authorization mechanism.
I'm researching a possibility of using some cloud storage directly from client-side JavaScript. However, I ran into two problems:
Security - the architecture is usually build on per cloud client basis, so there is one API key (for example). This is problematic, since I need a security per my user. I can't give the same API key to all my users.
Cross-domain AJAX. There are HTTP headers that browsers can use to be able to do cross domain requests, but this means that I would have to be able to set them on the cloud-side. But, the only thing I need for this to work is to be able to add a custom HTTP response header: Access-Control-Allow-Origin: otherdomain.com.
My scenario involves a lots of simple queue messages from JS client and I thought I would use cloud to get rid of this traffic from my main hosting provider. Windows Azure has this Queue Service part, which seems quite near to what I need, except that I don't know if these problems can be solved.
Any thoughts? It seems to me that JavaScript clients for cloud services are unavoidable scenarios in the near future.
So, is there some cloud storage with REST API that offers management of clients' authentication and does not give the API key to them?
Windows Azure Blob Storage has the notion of a Shared Access Signature (SAS) which could be issued on the server-side and is essentially a special URL that a client could write to without having direct access to the storage account API key. This is the only mechanism in Windows Azure Storage that allows writing data without access to the storage account key.
A SAS can be expired (e.g., give user 10 minutes to use the SAS URL for an upload) and can be set up to allow for canceling access even after issue. Further, a SAS can be useful for time-limited read access (e.g., give user 1 day to watch this video).
If your JavaScript client is also running in a browser, you may indeed have cross-domain issues. I have two thoughts - neither tested! One thought is JSONP-style approach (though this will be limited to HTTP GET calls). The other (more promising) thought is to host the .js files in blob storage along with your data files so they are on same domain (hopefully making your web browser happy).
The "real" solution might be Cross-Origin Resource Sharing (CORS) support, but that is not available in Windows Azure Blob Storage, and still emerging (along with other HTML 5 goodness) in browsers.
Yes you can do this but you wouldn't want your azure key available on the client side for the javascript to be able to access the queue directly.
I would have the javascript talking to a web service which could check access rights for the user and allow/disallow the posting of a message to the queue.
So the javascript would only ever talk to the web services and leave the web services to handle talking to the queues.
Its a little too big a subject to post sample code but hopefully this is enough to get you started.
I think that the existing service providers do not allow you to query storage directly from the client. So in order to resolve the issues:
you can write a simple Server and expose REST apis which authenticate based on the APIKey passed on as a request param and get your specific data back to your client.
Have an embedded iframe and make the call to 2nd domain from the iframe. Get the returned JSON/XML on the parent frame and process the data.
Update:
Looks like Google already solves your problem. Check this out.
On https://developers.google.com/storage/docs/json_api/v1/libraries check the Google Cloud Storage JSON API client libraries section.
This can be done with Amazon S3, but not Azure at the moment I think. The reason for this is that S3 supports CORS.
http://aws.amazon.com/about-aws/whats-new/2012/08/31/amazon-s3-announces-cross-origin-resource-sharing-CORS-support/
but Azure does not (yet). Also, from your question it sounds like a queuing solution is what you want which suggests Amazon SQS, but SQS does not support CORS either.
If you need any complex queue semantics (like message expiry or long polling) then S3 is probably not the solution for you. However, if your queuing requirements are simple then S3 could be suitable.
You would have to have a web service called from the browser with the desired S3 object URL as a parameter. The role of the service is to authenticate and authorize the request, and if successful, generate and return a URL that gives temporary access to the S3 object using query string authentication.
http://docs.aws.amazon.com/AmazonS3/latest/dev/S3_QSAuth.html
A neat way might be have the service just redirect to the query string authentication URL.
For those wondering why this is a Good Thing, it means that you don't have to stream all the S3 object content through your compute tier. You just generate a query string authenticated URL (essentially just a signed string) which is a very cheap operation and then rely on the massive scalability provided by S3 for the actual upload/download.
Update: As of November this year, Azure now supports CORS on table, queue and blob storage
http://msdn.microsoft.com/en-us/library/windowsazure/dn535601.aspx
With Amazon S3 and Amazon IAM you can generate very fine grained API keys for users (not only clients!); however the full would be PITA to use from Javascript, even if possible.
However, with CORS headers and little server scripting, you can make uploads directly to the S3 from HTML5 forms; this works by generating an upload link on the server side; the link will have an embedded policy document on, that tells what the upload form is allowed to upload and with which kind of prefix ("directories"), content-type and so forth.