OAuth Token as Salesforce SessionId in SOAP API (PHP)

Sunday, October 7, 2012 by Aslam - The Alexendra
Hi All,
Most of the time developers who write applications in php/java or any other language, using salesforce soap APIs (partner wsdl or enterprise wsdl), they hard-code the username/password and security token in their code or in a property file. But there is one issue in this approach, anytime, if your org password or security token get change, your application may down. You have to update the credentials in your code or property file on server to get your application work.

One alternate solution for this issue is to use OAuth token in your code and write one automated code which will refresh your oauth token whenever it gets expired. The approach which i am going to tell in few moments has a benefit that you don't have to modify your code much. The place where you setting your sessionid, you just need to change that place, instead of getting sessionid from login method, you simply need to change with oauth token way.

Here is a complete process to achieve this:


1) Go to your org, Setup->Remote Access, make New remote access entry there for your application. Give return url for the file which will get oauth code returned. In my example, i used this url
http://localhost/oauthsample/tokenprint.php




You will notice that you will get Consumer key and Consumer secret.

2) Make one php file at this location oauthsample/tokenprint.php with below code. The purpose of this code is simply print the oauth code.
<?php var_dump($_REQUEST); ?>


3) Now use your browser, prepare this url and invoke from address bar of browser
https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<your_consumer_key>&redirect_uri=http://localhost/oauthsample/tokenprint.php
 

As soon you invoke this url, you will see the generated oauth code on screen, copy the "GENERATED CODE" from the browser window.

4) Now use following html code, run it in your browser, by simply double click, fill the values in each field.


<form method="post" action="https://login.salesforce.com/services/oauth2/token"> <input type="hidden" name="grant_type" value="authorization_code"/> <table> <tr> <td> GENERATED CODE </td> <td> <input type="text" name="code" /> </td> </tr> <tr> <td> CONSUMER KEY </td> <td> <input type="text" name="client_id" value=""/> </td> </tr> <td> CONSUMER SECRET </Td> <td> <input type="text" name="client_secret" value=""/> </td> </tr> <tr> <td> REDIRECT URL </td> <td> <input type="text" name="redirect_uri" value="http://localhost/oauthsample/tokenprint.php"/> </td> </tr> </table> <input type="submit" /> </form>











5) After you execute this, you will get xml output on screen something like this:





Here you will get two important things, one Refresh Token and second "access token".

6) Now, in your PHP/Java code you need to replace your session id with this access token. There is another thing in your code "server url", this you need to hard code something like below (make sure to use instance url of your org) :

$mySoapClient = $sfConnection->createConnection('partner.wsdl'); $serverUrl = "https://ap1.salesforce.com/services/Soap/u/25.0/00D90000000Abcd"; $sessionId = "<<ACCESS TOKEN>>"; $mylogin = $sfConnection->attach($serverUrl, $sessionId);



7) Now, how to deal with expired token? For that you need to either make a separate method for it, or simply you need enclosed you code in try, catch block and look for INVALID SESSION exception. That exception will come whenever you try to access server contents and your token is expired. So the idea is, whenever that happen , simply catch that exception and use below code to get new access token. In below code, simply replace the different fields with your org info like consumer key, secret and important "REFRESH TOKEN" which we got in step #5.


<?php function getNewToken(){ try{ $url = 'https://login.salesforce.com/services/oauth2/token'; $fields = array( 'grant_type' => "refresh_token", 'client_id' => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 'client_secret' => "xxxxxxxxxxx", 'refresh_token' => "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } $ch = curl_init($url); //set the url, number of POST vars, POST data curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //execute post $result = curl_exec($ch); //close connection curl_close($ch); $json_a=json_decode($result,true); return $json_a; }catch(Exception $e){ var_dump($e); } } ?>

You can simply call this method getNewToken() to make new token whenever needed.

You are now all set, now you don't have to worry about user credentials updation or revealing it.

Let me know if you face issue in any step.

Thanks
Aslam Bari

19 comments:

Sji Infotech Pvt Ltd. said...

Hi,
its really nice post. i apprentice for your post. thanks for shearing it with us. keep it up. Please visit any web development like Php, CSS, CMS, HTML, WordPress, seo and other : www.sjiinfotech.com

Abdul Vahid said...

Very Nice once again :)

Unknown said...

Nice post - Thanks for it. However - I always get a sign-on screen on the first step. Is that normal?

Aslam - The Alexendra said...

Hi Jeff,
Yes, that is normal, and you will get that screen.
Actually I should mention that in my post that in your first step, you will get authorization prompt, you need to login in your org and Allow access to it.

Vikas gaur said...

Awesome..........

Akhilesh Soni said...

gr8 post aslam dada :)

Unknown said...

Very helpful and timely as we are now looking into integrating QuickBooks with Salesforce.

Unknown said...
This comment has been removed by the author.
Jean-Philippe Monette said...

I highly suggest to use an OAuth2 class to manage all the credential part to simplify the process. There's an extension available for PHP, but also a couple of classes, generic OAuth2 classes that can be customized with the appropriate endpoints.

Lokesh said...

very informative.. nice post !!

ehime said...

This would be extremely helpful but the PHP Toolkit does not have an "Attach" method? Where are you getting this from??

Aslam - The Alexendra said...

@ehime, please check newer version of php toolkit, hope you will get that method. If not, mail me , i will give you the version which has that method.

ehime said...

@Aslam Works great now. Something to note is that after switching over to the v20 REST api, a lot of the functions in the v11-13 Toolkit have been removed!!

If anyone is missing functions/methods, go get the OLDER PHPToolkit and copy/paste them back over, most are in SforceBaseClient.php !!!

M. said...

I'm also missing the ->attach() method call.
I tried downloading v11 and v13 but the method isn't on those toolkits either.

If you could please publish that, or send me the code via email, or tell use how to get it, it would be awesome!

Thanks!

Seth Carstens said...

I can't find the attach() method anywhere either. I see lots of REST examples now, but I was kinda hoping to use SOAP instead of relying curl. Did anyone find where this method came from?

seth at sethmatics.com

Aslam - The Alexendra said...

Hi All,
Few people asked this questions attach() method is not found. That will be found in latest soapclient library if you have. If you dont have please email me, i will forward the updated folder which you can use.
I have send email to few peopled asked.

Anonymous said...

Hi,

This is very nice and useful post.

I want to Fetch Salesforce user info using OAuth. How can I do it.

Anonymous said...

Any information regarding the expiry time of access_token and how to set it?

Unknown said...

Aslam (or anyone else), can you please send me toolkit with attach method? Thanks! Gmail: makingmemark at gmail dot com

Post a Comment