I have a form on my WordPress website that collects additional information from Leads. I want this information added to an existing Lead record, so I made a WordPress plugin that initializes a cURL PATCH
request like so:
I'm able to do this because I'm exposing a public API via an Apex class. Yeah, I know it's not as secure as OAuth, but I want non-logged in users to be able to submit the form. I would use Salesforce's Username-Password OAuth flow for this, but it has come to my attention that it is not secure and should only be used for development with Sandboxes (source). Additionally, the API that I am exposing is quite limited (you can't create new records or delete existing ones; you can only edit a few custom fields of a record).
Here is a demonstration of the kind of API that I am exposing:
@RestResource(urlMapping='/myendpointgoeshere/*')
global class FooBar {
@HttpPatch
global static void doPatch(String someEmailAddress, String theNewFieldVal) {
// indented so you can clearly see what's going on
List<MyCustomObject__c> results = [
SELECT Some_Field__c
FROM MyCustomObject__c
WHERE Email__c = :someEmailAddress
];
for(MyCustomObject__c o : results){
o.Some_Field__c = theNewFieldVal;
}
update results;
}
}
Here is the PHP class method that initializes the cURL request; it is called after the form is submitted.
Basically, it is posting three field values to my Force.com site.
public function patch_salesforce($field1, $field2, $field3) {
$url = 'https://<MY_INSTANCE>.force.com/<MY_SITE>/services/apexrest/...';
$content = json_encode(array(
'field1' => $field1,
'field2' => $field2,
'field3' => $field3
));
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if($status != 200) {
die("Error: call failed with status $status, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
}
This code works without any errors. I know this because I tested it with my Sandbox, but now I want to take it live, so I swapped out the Sandbox Force.com URL with the Production org's URL.
After doing so, I'm met with this error:
Error: call to URL failed with status 0, curl_error SSL: no alternative certificate subject name matches target host name '<MY_INSTANCE>.force.com', curl_errno 51
I spent some time researching cURL error code 51. I was presented with the following solution from this StackOverflow post.
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
I'm hesitant to use that solution because it is insecure and can leave me vulnerable to a Man-in-the-Middle attack. Many people don't recommend using it. Also, it seems like a "lazy" fix.
My questions:
- Is there any other way to fix this?
- Is the problem with my web host, website, or Salesforce?
- Should I be concerned with Man-in-the-Middle attacks?
- Should I use the "lazy" solution above?