function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Adam Drissel 1Adam Drissel 1 

Getting API Session ID within Lightning Apex Controller

I am trying to make a call to the REST Api from my Lightning Component.  There is a section in the Lightning Components Developer Guide specifically addressing this:

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_api_calls_platform.htm?search_text=api%20call

The relevant portion states: "Sometimes, you have to make API calls from server-side controllers rather than client-side code. In particular, you can’t make calls to Salesforce APIs from client-side Lightning component code. For information about making API calls from server-side controllers, see Making API Calls from Apex."

When you click on that link it takes you to the following portion of the Lightning Components Developer Guide (please note that ALL of this is thus far in the Lightning developer guide):

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/apex_api_calls.htm#apex_api_calls

The relevant portion there is "To call Salesforce APIs, make the API calls from your component’s Apex controller. Use a named credential to authenticate to Salesforce." 

In the middle section on that page it states: "By security policy, sessions created by Lightning components aren’t enabled for API access. This prevents even your Apex code from making API calls to Salesforce. Using a named credential for specific API calls allows you to carefully and selectively bypass this security restriction."

This seems to read very simple.  If you want to make an API call from your Lightning component, you need to do so from the Lightning Apex Controller, and make sure you use a Named Credential to authenticate.  Here is my named credential data (details on setup found here: https://developer.salesforce.com/docs/atlas.en-us.208.0.apexcode.meta/apexcode/apex_callouts_named_credentials.htm)

User-added image
My setup is identical to the one in the Apex Developer Guide (linked above).  Here are the relevant portions of my Lightning code:

Component
<aura:component implements="force:appHostable" controller="Case_QuickCreateController">    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
</aura:component>

Lightning Controller
({    
    doInit : function(component, event, helper){
        helper.callApi(component);
	}
})

Lightning Helper
({
    callApi: function(component) {
        var action = component.get("c.callRestApi");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS" && response.getReturnValue() != '') {
                // "populate data here"
            }
            else if(state === "ERROR"){
                console.log('A problem occurred: ' + JSON.stringify(response.error));
            }
        });
        
        $A.enqueueAction(action);
    }
})

Apex Controller
public with sharing class Case_QuickCreateController {
	@AuraEnabled
    public static String getSFDCInstance(){
        return System.URL.getSalesforceBaseURL().toExternalForm();
    }

	@AuraEnabled
    public static void callRestApi(){
        String instance = getSFDCInstance();
        String url = 'callout:LightningAPICallout/services/data/v40.0/sobjects/Case/describe?format=json';
        
        Http h = new Http();
        
        HttpRequest req = new HttpRequest();       
        req.setEndpoint(url);
        req.setMethod('GET');
        
        HttpResponse res = h.send(req);
        String body = res.getBody();
        
        system.debug(body);
    }
}

The resulting HttpResponse and message in the Debug Log are:
System.HttpResponse[Status=Unauthorized,StatusCode=401]

{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}

I am following all of the documentation to a "T".  Why am I still not getting a valid session Id and subsequently being authorized?

Please help ASAP!
 
Lindsay Holmes 8Lindsay Holmes 8
You need to manually set the Authentication header to use a merge field from your Named Credential (see https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials_merge_fields.htm). First, update your Named Credential to allow merge fields. Then add this to your callout:
req.setHeader('X-Username', '{!$Credential.UserName}');
req.setHeader('X-Password', '{!$Credential.Password}');