Part 1:
(Preface, or "Why you shouldn't care")
As you mentioned that you that you will be using Parse.com as the backend - let's take a look how this product approaches the same problem, while providing their service to developers:
They give you two "public" keys that you put in the JS SDK that they provide. Those keys are visible for any visitor of the developer's web app by looking at the page's HTML source code and in theory - any visitor can create a "replica" of his service by copy pasting those keys and reusing the developer's JS files.
Parse is not concerned by this, and they shouldn't be, since they just provide a means to an end. They give you the possibility to build a fully functional web app, using Parse as its backend but they don't care how you will make sure that it's just your web app that communicates with the Parse APIs. They also limit/track usage on your requests by API keys - the thing that relates to your question.
JavaScript is inherently insecure (by the fact that it's a client side language and not server side). There is no way for the developer to make sure that a malicious end user doesn't acquire his API keys from the page source and use them to communicate to his Parse project (at least, not without some sort of internal proxy tunneling script that serves as a middleman between his client side app and the actual Parse API calls in a "server-to-server" manner, without exposing the Parse client keys to the end user in the process).
This being said, an entirely "client side" based web app should be always architectured in a way that anticipates such malicious users, e.g. no "private" resources should be exposed to the end user without him first being authenticated (read more on Parse ACL in the official JS guides).
Given the above information, there is still a way to make sure that a given API key is only used by the domain it was given to, although not that easy:
Part 2:
(Practical example using an external .js in <head>
- "the Google Analytics way")
Let's think of how another popular web based service works - Google Analytics (or any other analytics service). They give you a piece of JS that basically does this:
- Includes a remote JS in the current page (one that is hosted by your server and provided by your server).
- Initializes the logic from that remote JS using the client's "public key" (in the case of Google Analytics, the Analytics Web Property ID)
You can approach your problem in a similar manner: expose a JS resourse, that is actually generated on the fly by your server. Let's say your service is called http://example.com. You can expose a JS that your clients can include in the <head>
part of their page using:
<script src="http://example.com/cool_library_helper.js?api_key=XXXXXXXX"></script>
This JS resource is just a masked dynamic script on your server, so you can do whatever security calculations necessary inside. As a minimum, that script should:
- Get the current browser URL (the domain, that included/loaded your external helper JS).
- The passed API key (passed as GET parameter to the JS file).
- Generate (on the server side) a unique, secure, hashed and salted, time-based one time token that will be used just to call a secondary helper API endpoint on your service, let's call it /api/getToken.
The API endpoint from the last step should take the 3 pieces of information (the last one being pretty much impossible for a potential hacker to spoof), check ALL of them for validity and as a result, return the final secret token to the client's app, that it can now use to communicate with your other service API endpoints from now on.
The advantages of this approach is that the public keys that you provide to your client are just a means for the end user to exchange them for the actual temporary token that he will use to communicate with your APIs, which means that you can expire and revoke access to any temporary token on your service. Additionally, you are validating in your service (server side) that the calling domain matches the one that is paired with the API key and only then you are giving the secure token to the final user.
Not ideal, but this is as secure as client side apps get.
PS: As an additional reading resource, I would recommend this answer.