DEV Community

Cover image for Obtain Salesforce Session Id through Visualforce, Anonymous Apex, or Cookie Retrieval (and avoid SESSION_ID_REMOVED)
Jonathan Bowman
Jonathan Bowman

Posted on • Edited on

Obtain Salesforce Session Id through Visualforce, Anonymous Apex, or Cookie Retrieval (and avoid SESSION_ID_REMOVED)

The Salesforce Session Id is a token representing a user's authenticated session, and must be used to make API calls as that user, such as this example using curl:

curl https://my_domain.my.salesforce.com/services/data/v47.0/ -H 'Authorization: Bearer 00D000000000abc!ABcABCDp0ABCdeZgn30EabcFpg7.v.xyzxO_abcEqh7PLqYY4Ea6XBV.ab5ct07AB4cp.5jDEFHtDaHTp_ABCfgFkhF8P7EQ'
Enter fullscreen mode Exit fullscreen mode

Replace "my_domain" with your Salesforce org's My Domain, and replace the fake Session Id with the real one, and you should see a list of service endpoints in JSON.

Security bulletin

If you are copying out your Session ID, leaving it in logs, your clipboard, your command-line history, or even your code, do yourself a favor and log out of Salesforce as soon as you are done with your API work. Once logged out, the Session Id is invalid, so session hijacking using that Session Id is impossible. Until that point, though, you are vulnerable. And, of course, do not commit your Session Id to version control (such as git).

There are three ways I have used to obtain the Session Id: a Visualforce page, Anonymous Apex in Developer Console, or, my favorite, retrieving a cookie from the browser using a bookmarklet.

Using a Visualforce page with $Api.Session_ID

I sometimes make a Visualforce page that displays the Session Id. Something like this works fine:

<apex:page>
{!$Api.Session_ID}
</apex:page>
Enter fullscreen mode Exit fullscreen mode

I usually label it "0SessionId" so that it appears at the top of this list in Setup -> Visualforce Pages. Of course, make sure the Name does not start with a number, due to the sacred laws of Salesforce API names.

Why stop there? The following page makes it fairly convenient to copy out the Session Id.

<apex:page showHeader="false">
<html>
<head>
  <title>Session Id for {!$Organization.Name}</title>
  <style>
      input {
        font-family: monospace;
        width: 112ch;
      }
  </style>
  <script>
      function copyId() {
        var idField = document.getElementById("sfsessid");
        idField.select();
        document.execCommand("copy");
      }
  </script>
</head>
<body>
  <p><input id="sfsessid" size="112" type="text" value="{!$Api.Session_ID}"></input></p>
  <p><button onclick="copyId()">Copy Session Id</button></p>
</body>
</html>
</apex:page>
Enter fullscreen mode Exit fullscreen mode

After page creation, click the Quick Save then the Preview button to find the Session ID. I don't recommend installing this as a Visualforce tab; just preview the page when you need the Id.

Using Anonymous Apex in the Developer Console and UserInfo.getSessionId()

In the Developer Console, press Ctrl/Cmd-e to launch the Anonymous Apex window. One would think the following would work well:

System.debug(UserInfo.getSessionId());
Enter fullscreen mode Exit fullscreen mode

But after executing, the debug logs show SESSION_ID_REMOVED rather than the Session ID. This is a security feature. We would not want to leave this key to our user session lying around in our logs.

Anonymous Apex Solution #1: mangle the Session ID

If you are convinced leaving Session Ids in your debug logs is an acceptable risk, you can try mangling them just enough for Salesforce to leave them alone. For instance, try splitting the Session Id with a space somewhere in the middle:

void sessIdSplit() {
    String sessId = UserInfo.getSessionId();
    System.debug(sessId.substring(0,50) + ' ' + sessId.substring(50));
}

sessIdSplit();
Enter fullscreen mode Exit fullscreen mode

Copy it out of the debug log, then remove the space before using it.

Not terribly convenient or secure.

Anonymous Apex Solution #2: place the Session ID in a private Note

For this option, first make sure the new Notes feature is enabled in your org.

void sessIdNote() {
    ContentNote cn = new ContentNote();
    cn.Title = 'Session Id for ' + UserInfo.getName() + ' ' + System.now().format();
    cn.Content = Blob.valueOf(UserInfo.getSessionId());
    cn.SharingPrivacy = 'P';
    insert cn;
}

sessIdNote();
Enter fullscreen mode Exit fullscreen mode

Now, in the App Switcher, select Files, and you should see a note with the Session Id in the content. Blank out the content and delete it when you are done, and, once again, log out of Salesforce to invalidate the Session Id.

Anonymous Apex Solution #3: place the Session ID in a Task

void sessIdTask() {
    String userId = UserInfo.getUserId();
    Task t = new Task();
    t.OwnerId = userId;
    t.Subject = 'Session Id for ' + UserInfo.getName() + ' ' + System.now().format();
    t.Status = 'Open';
    t.Priority = 'Normal';
    t.Description = UserInfo.getSessionId();
    insert t;
}

sessIdTask();
Enter fullscreen mode Exit fullscreen mode

This is similar to the Note solution above, but with a Task in case you don't have Notes enabled. When all done using the Session Id, blank out the Task description (you might cut instead of copy), mark it complete, and logout.

Retrieving a cookie with Javascript in a bookmarklet

This is the one that I use and love. Convenient, and more secure than the above solutions.

Bookmarklets reside in your bookmarks, and allow you to execute arbitrary Javascript on any web page you choose.

Install the one I wrote below. You can trust me.

Yeah... Maybe you should understand what it does first.

The following snippet, once you feel good about it, can be selected and dragged to your bookmarks bar

javascript:(() => {let apipath='/services/data/'; if (location.pathname === apipath) {let sessid = (';' + document.cookie).split("; sid=")[1].split("; ")[0];  navigator.clipboard.writeText(sessid);} else {window.open(location.origin + apipath, "_blank");}})();
Enter fullscreen mode Exit fullscreen mode

Once there, you first login to your Salesforce org, then click the bookmarklet. You will usually need to click it twice (once after the redirect).

Here is a prettier version:

javascript: (() => {
  let apipath = "/services/data/";
  if (location.pathname === apipath) {
    let sessid = (";" + document.cookie).split("; sid=")[1].split("; ")[0];
    navigator.clipboard.writeText(sessid);
  } else {
    window.open(location.origin + apipath, "_blank");
  }
})();
Enter fullscreen mode Exit fullscreen mode

The bookmarklet, once clicked, will check if the current page is the Salesforce services endpoint for this org. If it is not, it will redirect to that endpoint so that we can be ensured that we are on the correct subdomain for future API calls. Once there, the bookmarklet needs to be clicked again, and it will find the cookie with the name "sid" and copy the value (the Session Id) to the clipboard.

Do you need a bookmarklet? Not necessarily. You can open the Chrome DevTools Console, select the Application tab, expand Cookies and copy out the sid cookie. Just make sure you are on the same domain that you intend to make API calls to, so you get the right cookie.

Again, when you are done with the Session Id, it is a good idea to logout of Salesforce.

Enjoy your Salesforce API calls.

Top comments (2)

Collapse
 
kritikgarg profile image
kritikgarg

πŸ”‘πŸ’»Great post, Jonathan! Your detailed explanation on how to obtain a Salesforce session ID using various methods like Visualforce, Anonymous Apex, and Cookie Retrieval is really helpful. This will definitely help developers avoid the common issue of SESSION_ID_REMOVED. Thanks for sharing!πŸ‘

Moreover,πŸ”ŽπŸ“ Recently i came across an article The Ultimate Guide about Salesforce Org ID, which can be a valuable resource for those who are learning how to locate the Org ID in Salesforce.πŸ’‘

Collapse
 
davekenroberts profile image
David Roberts

Found this neat workaround

System.debug(System.UserInfo.getSessionId().SubString(15));
Enter fullscreen mode Exit fullscreen mode

at: SFDCFacts Academy