0

I am working on integrating a native android and iOS project into a Salesforce environment. We have successfully ran the forcedroid and forceios commands to get functioning projects and have been able to login to our Salesforce sandbox using our Salesforce accounts. However, our users do not have Salesforce accounts, they use an authenticated site/customer portal.

It would seem as though the Salesforce Trailhead Module is greatly geared towards Community logins, which does not work with our existing situation. I've read a bunch of documentation, but haven't been able to find anything that would point me in the right direction for using the Mobile SDK with a customer portal.

At this point we are wondering if we need to throw out the SDK and manage everything ourselves by POSTing to the portals login. Any information/suggestions/guidance on this would be extremely helpful.

edit:

After more investigation we are starting to wonder if we want to be utilizing the login_portal.jsp and mimic the request. Theoretically we could determine based on the response if we have a valid token or not. However, requesting any other pages is causing a redirect back to the login page which seems to be a no go. It's possible that we are missing some part of the header, but when watching the browser do login it jumps through several hoops frontfoor -> portaldoor -> home.

Even in the event with a valid token, I'm not sure how we would go about requesting data for the user anyway, since I don't believe I would be able to hit any of the REST endpoints as a user is not a Salesforce user.

Again, any help or suggestions would be greatly appreciated!

  • If you're not using oAuth via a connected app, the SDK won't help you. It's possible to do oAuth with site/portal. I would say you really have to know the guts of the protocol and SF implementation to go this route. – identigral Jul 23 at 16:56
1
+50

I can't say I'm really a fan of this solution, but until a better interface is made known or available, I had to rely on interacting with the login portal via a requests library, and parse needed information from various VisualForce pages with an HTML parsing library.

This kind of behavior can be compartmentalized into a backend to some extent, which at least leaves all of the hacks together in one component that can hopefully be addressed later.

If one were to use python, requests can be used to open a session and maintain a cookie store after logging in, and then beautifulsoup4 can be used to parse HTML if required.

import requests
from bs4 import BeautifulSoup

s = requests.session() # Make a session for all requests
base_url = 'https://your_instance.salesforce.com'

A login method could be used to return the response from an authentication attempt:

def login(username, password):
  data = {
    'startURL': '',
    'loginURL': '',
    'useSecure': True,
    'orgId': 'you_org_id',
    'portalId': 'your_portal_id',
    'loginType': 3,
    'action': 'loginAction',
    'un': username,
    'pw': password,
  }

  return s.post(F'{base_url}/secur/login_portal.jsp', data=data)

You may find that the responses are far from ideal, and return 200 in the case of a success or failure (unless you disable redirects, in which a failure generally returns a 200, and a success returns a 302). And you might need to read the html from the response to determine the status.

Getting user information, or any information at all from the visual force page is where this hack begins to fall apart. Ideally, you can have your organization provide a VisualForce page with some kind of plain-text (or JSON formatted) data with no styling made available, and you can just digest that page to retrieve specific user information.

def get_user_details():
  r = s.get('https://c.your_instance.visual.force.com/apex/your_details_page')
  soup = BeautifulSoup(r.text, 'html.parser')
  table = soup.find('table', {"class": "myCoolTable"})
  res = {}
  for label, td in zip(table.find_all("label"), table.find_all("td")):
    key = label.text.strip()
    val = td.text.strip()
    if key:
      res[key] = val
  return res

This is just a quick demo, but one could potentially wrap these features into a backend framework such as Flask or Django to create a useable interface for other apps and components to consume.

if __name__ == '__main__':
  r = login('your_email', 'your_password')
  print(get_user_details())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.