How to call a Salesforce REST URL from Lightning Component?
Marty is correct, although I would like to temper the description of this being "unfortunate" a bit with some background on why the security policy is in place. In order for us to satisfy our internal security audits and architectural reviews which allowed us, for the first time ever in our presentation layer, to provide a supported mechanism to allow salesforce authored code and customer/ISV/partner authored code to coexist in the same JavaScript space we had to tighten things down significantly. Here are some of the things currently enforced:
- Content security policy, or CSP, a relatively new browser technology that allows us to have fine-grained control over access to all external references to scripts, images, stylesheets, etc. Our policy is extremely restrictive right now and not extensible but we had plans to open up a white listing capability in the near future.
- Lightning applications are served from a separate domain in much the same manner that visual force pages are today. The difference here is that you are actually in the same application, running right next to our client-side code and not relegated to live in an iframe silo. Those silos have presented significant challenges around producing high performance, high fidelity, engaging user experiences that integrates directly into core salesforce functionality for many years.
- The lightning application separate domain also uses a special lightning session ID that does not have direct API access. The fact that you can currently provide indirect access to a fully API capable session ID is a great example of why our content security policy is currently so restrictive. Leaking an API said back to the client in a way that malicious JavaScript can easily steal is precisely why we have things locked down so tightly today. What should happen if you attempted to serialize an API session ID from an apex controller? That session ID is supposed to be the same restricted access Aura session ID but we apparently have a leak in that underlying logic. Our belt and suspenders approach with CSP combined with serving from a separate domain actually thwarted this potential attack.
Why did we do these things? Most of it boils down to "protect Setup". Without these safeguards in place is almost trivial for malicious client side code to gain height and privileges and access to administrative level functionality by remote controlling the setup user interface Also, much of what we have done so far represent cross site scripting (XSS) attack countermeasures.
There is definitely much more to the story but hopefully this gives you some of the back story to better understand our decisions and direction. This is not the end, rather just the beginning, and we are hard at work on improving and refining our approach to balancing the security requirements that we have to satisfy along with providing all of you with the tools that you need to build what you want.
Peter, the unfortunate answer (I think) is that based on how Lightning currently works in Winter '15, we may not have a direct way of connecting to any of Salesforce's REST APIs. As a workaround, it appears that you can leverage Apex as a conduit to the REST APIs.
The approach can be summarized as follows:
- Create an Apex client for the REST API
- Create an Apex controller for your Lightning app
- Create your Lightning app, and bind it to the controller
- Specify an
init
handler for your app - Configure the handler to enqueue the Apex controller's action to execute the REST API operation
I've confirmed that this approach works, at least in the sample app shown in this gist: https://gist.github.com/martyychang/6ef675e598838fa0013d
In 2015, Raja Rao wrote a Salesforce Developer Relations blog post explaining how you could host a VisualForce page in an iFrame and embed that in a Lightning Component, while passing messages back and forth using HTML5 postMessage.
Christophe Coenraets recently wrote a blog post explaining how to embed a VF page in an iFrame to allow communication that would otherwise be prohibited from a Lightning Component.
This is also the exact approach used by lightning:container to isolate 3rd party frameworks from a security pov. As of May 2017 that technology is still in Developer Preview (DE orgs and special permission only). A good comparison of LockerService and lightning:container was also given by Christophe Coenraets.