This flow is used to integrate an external web app with the Salesforce API, it implements the OAuth 2.0 authorization code grant type. With this flow, the server hosting the web app must be able to protect the connected app’s identity, defined by the client ID and client secret.
Throughout this topic, we'll dive into the key concepts of the Web Server Flow, and provide a step-by-step guide on how to implement it between two Salesforce orgs say ORG A and ORG B.
By the end of this session, you'll have a clear understanding of how to leverage the Web Server Flow to create robust integrations that facilitate smooth collaboration and data sharing between Salesforce environments. Let's get started!
The below steps explain the process involved in webserver flow.
- Request an Authorization Code
- Authenticate the User and Grant Access to the App
- Receive a Callback
- Request an Access Token
- Receive an Access Token
- Post Request
Let's start,
ACTIVITIES WE NEED TO DO IN ORG B.
1) Create a Connected App in ORG B.
2) Create a Webservice in ORG B which will be invoked from ORG A.
Create A Connected App In ORG B:
The connected app configured above under "How to configure a Connected App for the OAuth 2.0 Client Credentials Flow?" will work for web server flow as well as we have also enabled "Require Secret for Web Server Flow" check box. The below image also highlights callback URL of ORG A.
Create A Webservice As Shown Below In ORG B:
The createAccountRecord class is an Apex REST service that allows external systems to create Account records in a Salesforce org. It is exposed as a REST resource with the URL mapping '/createAccountRecord/*', meaning it can be accessed via HTTP requests.
This service defines a POST method, createAccount(), which expects JSON data containing information about the Accounts to be created. Upon receiving a request, the method deserializes the JSON payload, creates Account records based on the provided data, and attempts to insert them into the database.
If the insertion is successful, the method returns 'Success'. Otherwise, it returns 'Failure'.
The incoming JSON payload should adhere to the structure defined by the responseWrapper inner class, which includes fields such as Name, Description, Type, and Industry for each Account record.
This REST service provides a simple yet effective means for external systems to programmatically create Account records in the Salesforce org, facilitating seamless integration and data synchronization.
@RestResource(urlMapping='/createAccountRecord/*')
global with sharing class
createAccountRecord {
@HttpPost
global Static string createAccount(){
RestRequest req = RestContext.request;
RestResponse res = Restcontext.response;
string
jsonString=req.requestBody.tostring();
system.debug('jsonString'+jsonString);
boolean successCheck;
List<responseWrapper>
wRespList=(List<responseWrapper>) JSON.deserialize(jsonString,List<responseWrapper>.class);
Account obj=new Account();
List<Account> accList= new
List<Account>();
for(responseWrapper wResp: wRespList){
obj.Name=wResp.Name;
obj.Description=wResp.Description;
obj.Type=wResp.Type;
obj.Industry=wResp.Industry;
accList.add(obj);
}
try{
if(accList.size() > 0){
Insert accList;
successCheck=true;
}
}
catch(Exception e){
successCheck=false;
}
if(successCheck)
return 'Success';
else
return 'Failure';
}
global class responseWrapper{
global string Name;
global string Description;
global string Type;
global string Industry;
}
}
ACTIVITIES WE NEED TO DO IN ORG A.
Request an Authorization Code:
Hit the below URL to get the authorization code.
public class
responseWrapper {
public string id;
public string access_token;
public string instance_url;
}
public string cKey;
public string cSecret;
List < Store_Cred__mdt
> connectionParam = [SELECT Id, MasterLabel, client_id__c, client_secret__c
from Store_Cred__mdt];
if(connectionParam.size() >0){
cKey=connectionParam[0].client_id__c;
cSecret=connectionParam[0].client_secret__c;
}
System.debug('Store_Cred__mdt' +
connectionParam);
String authCode= 'aPrxsh*********************************************8Xg%3D%3D';
// The below URI is the callback URL of ORG A
String
uri='https://myknowndomain-dev-ed.my.salesforce.com/services/oauth2/callback';
String reqBody =
'grant_type=authorization_code&client_id=' + cKey + '&client_secret=' +
cSecret + '&code=' + authCode + '&redirect_uri=' + uri ;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setBody(reqBody);
req.setMethod('POST');
// Token end point of ORG B
req.setEndpoint('https://farukh-dev-ed.my.salesforce.com/services/oauth2/token');
HttpResponse hresp = h.send(req);
System.debug('hresp is'+hresp);
System.debug('hresp body
is'+hresp.getBody());
responseWrapper wResp =
(responseWrapper) JSON.deserialize(hresp.getBody(), responseWrapper.class);
system.debug('reqBody '+reqBody );
system.debug('wResp'+wResp );
system.debug('Instance url' + wResp.instance_url);
system.debug('session id' +
wResp.access_token);
List<Account> accList = new
List<Account>();
// End point of ORG B where we will send POST request for account record creation
string endPoint =
'https://farukh-dev-ed.my.salesforce.com'+'/services/apexrest/createAccountRecord';
accList=[SELECT
Id,Name,Description,Type,Industry from account Order By createddate DESC Limit
1];
Http h1 = new Http();
HttpRequest req1 = new
HttpRequest();
req1.setHeader('Authorization',
'Bearer ' + wResp.access_token);
req1.setHeader('Content-Type',
'application/json');
req1.setMethod('POST');
req1.setEndpoint(endPoint);
req1.setBody(JSON.serialize(accList));
HttpResponse hresp1 =
h1.send(req1);
system.debug('hresp1'+hresp1 );
system.debug('hresp1.getStatusCode()'+hresp1.getStatusCode());
system.debug('hresp1.getBody()'+hresp1.getBody());
if (hresp1.getStatusCode() == 200)
{
system.debug('Callout
Success');
}
No comments:
Post a Comment