How to authenticate SaleForce OAuth 2.0 JWT in PHP

salesforce

My name is Ume, I'm in charge of development. In this article, I'll show you how to use the PHPOAuth 2.0 JWT authentication method for SaleForce (verified in SandBox environment)We are pleased to introduce the
Salesforce is the world's No. 1 sales support and CRM tool, with a wide range of features including customer management, deal management, prospect management, sales forecasting, reports and dashboards, etc. If you want to synchronize Salesforce information with your own system, what should you do?

rest-api

Salesforce provides REST API and SOAP API for data exchange between servers, and this article explains how to use OAuth 2.0 JWT authentication to use those Web Service APIs.

Click here for table of contents

  • 1. create a private key and a self-signed digital certificate with OpenSSL
  • 2. create a Salesforce connection application
  • 3. create a JWT in PHP
  • 4. get an access token with PHP
  • 5. get information from SaleForce with PHP

 Create a private key and a self-signed digital certificate with OpenSSL

This certificate is for OAuth 2.0 authentication to verify that the JWT you passed to Salesforce is valid. Basically, you can use the Salesforce developer guideCreating a private key and a self-signed digital certificateYou can create it without any problem by referring to

Step 1: Generate a private key and save it in a file named server.key.

openssl genrsa -des3 -passout pass:any password -out server.pass.key 2048
openssl rsa -passin pass:any password -in server.pass.key -out server.key

Workflow 2. use the server.key file to generate a certificate signing request. save the certificate signing request in a file named server.csr.

openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [XX]:JP <- A 2 letter code indicating the country where the company is located. For Japan, the value is JP.
State or Province Name (full name) []:Tokyo <- Prefecture
Locality Name (eg, city) [Default City]:Taito <- city
Organization Name (eg, company) [Default Company Ltd]:tatsuno joho system <- company name (optional)
Organizational Unit Name (eg, section) []: <- Department name (optional)
Common Name (eg, your name or your server's hostname) []:lms.quizgenerator.net <- Common name (optional)
Email Address []:k.bai@tatsuno-system.co.jp <- email address (optional)
A challenge password []: <- not required
An optional company name []: <- not required

Workflow 3. generate a self-signed digital certificate from the server.key and server.csr files. save the certificate in a file called server.crt.

openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Directly under the path where the command was executed, four files are generated as follows, but what you will need is "server.key" and "server.crt".

    server.pass.key
    server.key
    server.csr
    server.crt

    The content of the primary key (for signing) "server.key" is like this.

    -----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEA09nuSOujeZ0AyR8gZ0jg0MOftWUD64IVJcIrULNCdv5/ZQ8H
    lvf6lOCs/77FWej07XZaNsBTpllX+yZSs3iFY+VZN/xW+6/e6+vARfPUL6IjnRIp
    drjXIj811qkvfeWXnZmJQgI7EurhwBgg2Oy2rcZFRL+KJGLhgD9cTkGr06dCIU/B
    
    ... Abbr...
    
    QYimkGrlPOzEcFEg/Md3n8UwZ7CSHIG0+xPp/8vnpqNmDPOCw7iEI4iJIyBuTkH4
    wzKOvJECgYAJ3ORif2l5LT4KCi5UZL27myUGqyDyt5VPa6H/RB3TChKtpnVcBBDF
    dCnvFqMv+AC3F2xFpcr3HK2l1H8Ya6yy7QMP9fqgHPWKrkpUSZcT/QvZniCreGsS
    7jbhD4R4VOPdu7I6cSWW+lA8mWTwK1Eym0FBl6d8i9q4GrxxcRTv2Q==
    -----END RSA PRIVATE KEY-----
    

    The content of the self-signed digital certificate (for verification) "server.crt" looks like this.

    -----BEGIN CERTIFICATE-----
    MIIDpDCCAowCCQDYJxgXlQ+UtjANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMC
    SlAxDjAMBgNVBAgMBVRva3lvMQ4wDAYDVQQHDAVUYWl0bzEcMBoGA1UECgwTdGF0
    c3VubyBqb2hvIHN5c3RlbTEbMBkGA1UEAwwSYmFpLnF1aXpnZW5kZXYubmV0MSkw
    
    ... Abbr...
    
    wpGlYCfAynDVPdE87rI5mitvPFfTAGn+M+kYTaVW4HqVvDMLX+X/3ID0aM5i+k3V
    8e2s/GvubOtcYty1nLf4IMtz6ikrfDfiHEmu2nqb+wrsKyvuTwVLakgdKKRYZgQv
    EIoWUaXAfGDGYyOOsrN6XWwpqp0Yzh51+v1nK+PDBd/fIufge6BDA5EDH3wAJjXu
    PeTR5HfZoXN5bdBk4KC4ueAGdw8ogbQJ
    -----END CERTIFICATE-----
    

     Create a Salesforce Connection Application

    Step 1: After logging in to Salesforce, open the "Settings" screen from the menu in the upper right corner.

    PHP

    Step 2: Open "Application Manager" from the menu on the left side of the configuration screen, and click "New Connected Application".

    php

    Set up the connection application. (Don't forget to "Save" after completing the settings.

    • Connection application name (optional content)
    • API reference name (include a clear description)
    • Business partner manager Email
    • Enable OAuth settings (must be checked)
    • Callback URL (not used, but it's a required field, so enter something appropriate)
    • Use digital signature (must be checked)
    • Self-signed digital certificate ("server.crt" created in the first step should be chosen)
    • The selected OAuth range
      If you use "full access (full)", you cannot get the access talk.

      • Provides access to data via the web (web)
      • Data access and management (api)
      • Perform requests on behalf of the user at any time (refresh_token, offline_access)

    All other settings can be left as default.

    php

    Click the "manage" button to open the administration screen. (For some reason, it is written in English here.

    php

    Click the "Edit Policy" button to open the Edit Policy screen.

    php

    Set the "OAuth Policy" as shown below. You can leave the other settings as default. Don't forget to click the "Save" button when you are done.

    Once the "OAuth Policy" is set to "Users approved by the administrator are pre-approved", the "Profile" can be set in the application management screen.

    php

    Workflow 7. Assign a profile to the application by clicking the "Manage Profile" button in the "Profile" settings area of the application's administration screen.

    php

    We want to retrieve and update data from Saleforce via REST API, so we assigned "System Admin" with full privileges here.

    If necessary, assign appropriate profiles.

    php

    After saving your profile settings, you will be automatically returned to the application management screen where you can check the results of your settings.

    php

     Creating a JWT with PHP

    The creation method published in the SaleForce developer's guide is here.

    I don`t know if the document is outdated or if it was a translation error, but there were a lot of mistakes and it was not helpful.

    The JWT (JSON Web Token) structure can be roughly divided into three parts, each separated by a ". separating them.

    • Header
    • Payload
    • Signature (Sinature)

    The entire JWT (JSON Web Token) string looks like this

    {header>} {Payload}. {signature}
    

    You can create an OAuth 2.0 JWT for SaleForce in PHP as follows

    Here I got stuck on the path of the file to pass to the openssl_pkey_get_private function.

    The file path must be written as "file://relative path or absolute path".

    function base64UrlEncode($data)
    {
        return str_replace('=', '', strtr(base64_encode($data), '+/', '-_'));
    }
    
    $header = base64UrlEncode(json_encode([.
        'alg' => 'RS256',
    ]));
    
    /**
     * About aud.
     * Production: https://login.salesforce.com
     * Sandbox: https://test.login.salesforce.com
     * Scratch Organization: https://test.saleforce.com
     */
    $payload = base64UrlEncode(json_encode([.
        //iss If you get it wrong, you'll get the error message 'The connection application does not exist.
        'iss' => 'The consumer key of the SaleForce connection application created in the previous step',
        'aud' => 'https://test.salesforce.com',
        //sub If wrong, error message 'Invalid user' will be returned.
        'sub' => 'SaleForce user's login ID',
        //The expiry time here is quite random, if exp is wrong you'll get the error message 'Talk expired'.
        'exp' => time() + 3 * 60,
    ]));
    
    /**
     * About signatures.
     * Use the "server.key" created in the previous step to write the JWT header and payload.
     */
    $signature = null;
    $privateKey = openssl_pkey_get_private('file://server.key');
    openssl_sign($header . '.' . $payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
    openssl_free_key($privateKey);
    
    $signature = base64UrlEncode($signature);
    $jwt = $header . '.' . $payload . '.' . $signature ;
    

     Obtaining an access token in PHP (using cUrl)

    You can access SaleForce side with PHP and issue an access talk as follows.

    $post = [
        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion' => $jwt, //the JWT string created in the previous step
    ];
    
    /**
     * About the API to get the access token.
     * Production: https://login.salesforce.com/services/oauth2/token
     * Sandbox: https://test.login.salesforce.com/services/oauth2/token
     * Scratch Organization: https://test.saleforce.com/services/oauth2/token
     */
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://test.salesforce.com/services/oauth2/token');
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);
    curl_setopt($ch, CURLOPT_TIMEOUT, 7);
    $response = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    if($httpcode == 200) {
        $json = json_decode($response, true);
        if(isset($json['access_token'])) {
            $access_token = $json['access_token'];
            //do something.
        }
    } else {
        var_dump($httpcode);
        var_dump($response);
    }
    curl_close($ch);
    

    As a result of the query, the following json data is returned.

    {
        "access_token" => "***********************************",
        "scope" => "web id api",
        "instance_url" => "https://SaleForce環境名.salesforce.com",
        "id" => "https://test.salesforce.com/id/*****/*****",
        "token_type" => "Bearer"
    }
    

     Get information from SaleForce with PHP

    One of the ways to query data published in the SaleForce developer's guide: theREST API/Query

    Data query method in PHP (using cUrl)

    $query = "SELECT field name FROM table name";
    $query = http_build_query(['q' => $query]);
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $access_token, //access token obtained in the previous step (string)
    ]);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_URL, 'https://SaleForce環境名.salesforce.com/services/data/v20.0/query/?' . $query);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);
    curl_setopt($ch, CURLOPT_TIMEOUT, 7);
    //Contact us
    $response = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $json = json_decode($response, true);
    curl_close($ch);
    

     summary

    In this article, we have shown you the steps to get data from SaleForce.
    learningBOX can also be integrated with SaleForce, please try it.

en_USEnglish