本篇參考:Salesforce Admin篇(四) Security 之Two-Factor Authentication & Single Sign On
一. Salesforce acting as IdP, IdP initiated
我們在前一個部落格中也解釋了 SSO中的 SP(Service Provider) 以及 IdP(Identity Provider),這裡舉一個簡單的例子進行深化概念。 help.salesforce.com 通過salesforce的賬號進行登入, salesforce端進行相關的賬號資訊認證,然後認證通過以後重新跳轉到 help.salesforce.com,然後根據你的sf賬號的許可權可以訪問相關的help中的文件以及操作。在這個demo中,help網址就是一個SP,用於提供服務,salesforce就是IdP,作為身份認證用。
我們在專案中通常使用 SF和其他的平臺做SSO,主要有三種的形式。
- Salesforce 作為 SP,其他系統作為IDP;
- Salesforce作為IdP,並且訪問SP的內容是由 IdP初始化;
- Salesforce作為IdP,並且訪問內容由SP初始化。
說起來有點繞,通過上面的參考的 SSO進行一個例子。我們之前的SSO實現的是salesforce to salesforce的功能。兩個salesforce的環境,其中:
- zero-zhang-dev-ed.my.salesforce.com:作為IdP;
- https://zhangyueqi-3-dev-ed.my.salesforce.com:作為SP;
現在的需求是從IdP的環境有一個URL,點選這個URL可以直接跳轉到SP環境的 Account 列表,這個時候,我們需要用到 RelayState引數。
首先我們需要知道如何可以不輸入賬號密碼就可以直接跳轉到SP 環境,通過 connected app,我們可以看到SAML Login Information區域有一個 IdP-Initiated Login URL,訪問此連結就可以直接跳轉到SP。
所以我們需要做的就是在這個URL基礎上,新增 RelayState引數,跳轉到對端系統的指定位置即可。Account 列表是 /001,所以我們設定 RelayState為/001即實現IdP Initiated的場景。
這裡需要注意一點, RelayState區分大小寫,只能按照當前的大小寫填寫,如果大小寫有誤,則會跳轉無效。
二. 標準 Rest API運算元據
我們和外部系統操作時,如果對端只是需要在我們這邊去簡單的運算元據,沒有複雜的邏輯,資料量也還好的情況下,我們完全可以使用標準的 Rest API去運算元據。這種好處是省去了我們寫restful介面以及兩邊系統溝通的時間,只需要瞭解標準的restful介面規則即可。
我們可以使用CURL方式去訪問去運算元據,我們通常操作型別是資料的CRUD,以及通過外來鍵進行C/U。接下來通過workbench進行簡單的模擬。
1. 查詢場景
1)通過Record Id去查詢:使用的Http方式為get,並且訪問的格式為 /services/data/v51.0(這裡填寫版本號)/sobjects/Account(這裡填寫表的API名稱)/Record Id。整體的cURL訪問:curl https://yourInstance.salesforce.com/ + 上述的格式即可。
如果我們只想查詢這條資料的指定的欄位,我們只需要在後面新增引數 ?fields=欄位名1,欄位名2。 欄位之間使用逗號分隔。
2) 通過外來鍵運算元據:我們知道的是,當一個欄位設定成外來鍵,他通常都是設定成external id & unique,所以通常通過 external id可以找到唯一的一條資料,在標準的rest api中,我們可以通過external id去獲取資料。和上面的寫法前面是一樣的,後者變化如下 /sObjectName/ 外來鍵欄位的API名稱/ 外來鍵欄位的值。在我們下方的demo中,我們在 Account表中建立了一個外來鍵,API名稱為 External_Id__c, 所以下面的連結是 External_Id__c為 Ext_00001的對應的Account資料
3) 通過SOQL語句進行查詢:標準 rest介面同樣支援使用SOQL去返回指定的list資訊。格式為:services/data/v51.0/query/?q=SOQL query, 其中 SOQL使用 + 分隔 。下面demo中在Account表中查詢了 Id以及Name。response中包含了記錄數以及細節資訊,可以通過層級結構進行資料的獲取。
2. 新建場景
1) 單表常規操作新建:針對表的建立,因為我們需要request body指定哪些欄位建立成哪些值,所以我們的method肯定不可能是 GET了,針對標準的單表建立,型別選擇Post,將報文內容放在{}(花括號)中間,然後使用鍵值對方式,左面是欄位的API Name,右面對應相關的值,按照以下的方式即可。點選Execute,我們可以看到 response的結構體返回了新建的Id,結果狀態等資訊。
2) 級聯表(nested records)建立資料:我們很多時候會有針對父子表的操作,標準的rest api同樣支援級聯表(lookup / master-detail)的建立,當然也只是支援建立操作,如果想要對級聯表進行更新或者刪除,需要使用相關的record id或者外來鍵去進行操作,此種操作只是支援新建。同樣先說一下request method,使用的是post。然後再說一下request URL為:/services/data/v51.0/composite/tree/Account/。這裡我們可以看到和上面的區別很大,使用的是 composite/tree,然後後面跟著的是級聯表父表的API Name。最後再說明一下request body,我們以下面的例子去進行具體的說明。下面的demo是建立兩條 Account資料,第一條Account資料要級聯建立 Contact資料自動關聯這條 Account,第二條 Account的資料要級聯建立Contact以及Case。這裡有兩個關鍵點需要說明:
- 每個層級結構中都有一個 referenceId:這個是必須要有的,並且是唯一的,當成功以後referenceId用來對應著成功插入資料的record id,這個可以隨便賦值,只要保證唯一即可。
- 我們看到針對子表插入的時候,使用的是 Contacts / Cases等。這個是子表和父表關聯時的 Child Relationship Name,因為這兩個都是標準表,所以沒有__r,如果是自定義表的關係,這個 Child Relationship Name後面需要新增 __r用來代表子表名稱。
request body 內容如下所示:
{
"records" :[
{
"attributes" : {"type" : "Account", "referenceId" : "ref1"},
"name" : "SampleAccount1",
"industry" : "Banking",
"Contacts" : {
"records" : [
{
"attributes" : {"type" : "Contact", "referenceId" : "ref2"},
"lastname" : "Smith",
"Title" : "President",
"email" : "sample@salesforce.com"
},{
"attributes" : {"type" : "Contact", "referenceId" : "ref3"},
"lastname" : "Evans",
"title" : "Vice President",
"email" : "sample@salesforce.com"
}
]
}
},
{
"attributes" : {"type" : "Account", "referenceId" : "ref4"},
"name" : "SampleAccount2",
"industry" : "Banking",
"Cases" : {
"records" : [
{
"attributes" : {"type" : "Case", "referenceId" : "ref5"},
"Status": "New",
"Priority": "Meduim",
"Origin" : "Phone"
}
]
},
"Contacts" : {
"records" : [
{
"attributes" : {"type" : "Contact", "referenceId" : "ref6"},
"lastname" : "Jones",
"title" : "President",
"email" : "sample@salesforce.com"
}
]
}
}
]
}
當我們使用這個 request執行以後對應的 response的層級結構如下,我們可以根據層級結構以及 referenceId檢視到指定的 recordId,然後可以通過 get方法獲取這條記錄的詳情資訊。
3. 更新 / Upsert 場景
1)通過記錄ID進行更新:根據前面的內容我們會發現 rest api需要確定的三個核心點: request method / curl / request body。針對記錄ID進行更新時, request method選擇 patch,curl和通過ID方式獲取資料的相同,為 /services/data/v20.0/sobjects/Account/recordId, request body和建立單條資料的方式相同,為鍵值對方式。demo如下:
需要注意的是,我們看 response內容覺得很怪,因為 update不返回相關的內容,我們可以通過status code來判斷,比如我們可以通過204去確定一下是否成功。status code狀態相關定義可以檢視此連結:https://developer.salesforce.com/docs/atlas.en-us.224.0.api_rest.meta/api_rest/errorcodes.htm
下面的demo來了一個報錯的情況,所以我們做update的場景也需要進行相關的異常捕獲。
2)通過外來鍵進行 upsert操作:和上面的三步走相同,upsert的request method為 patch,curl 和上面提到的通過外來鍵獲取資料相同,然後request body和上面的更新資料的報文相同。這裡直接來一個例子:
通過下圖我們可以看到報文和上面的外來鍵獲取資料相同,不做解釋,主要看一下 response body。success返回此次操作是否成功,成功情況下為 true,失敗的話為false,並且errors儲存錯誤資訊,created用來判斷當前操作是 insert還是 update,當前的demo為update,所以這項的返回值為false。
4. 刪除場景:當我們使用API去進行刪除時,request method選擇delete,url和通過record id獲取資料的url相同,沒有request body以及沒有response的body。我們可以通過status code來追蹤當前的刪除是否成功。通過下圖我們可以看到,刪除成功,沒有 response body,status code為204.
總結:本篇小結主要是兩點,一個是針對SSO的細節運用,一個是針對標準的 rest api相關的簡單介面操作。針對第二點講的也比較淺顯,如果真正第三方使用還需要配置 Oauth2.0等,詳情可以檢視API文件。這裡做一個有意思的引申,我們知道我們做 lightning專案的時候,以lwc為例。運算元據可以通過 LDS(lightning-record-form等)、 wire adapter(getRecord/ updateRecord等)以及後臺apex去做複雜的邏輯操作。通過上面的demo,我們是不是也可以考慮使用標準的 rest api去進行資料的操作?當然,Rest API不只是運算元據,還可以對schema進行相關獲取,很強大,建議可以快速掃一下。篇中有錯誤地方歡迎指出,有問題歡迎留言。