Loading
識別使用者與管理存取
目錄
選取篩選

          沒有結果
          沒有結果
          以下是搜尋小祕訣

          檢查關鍵字的拼字。
          使用較常見的搜尋字詞。
          選取較少篩選條件以擴大您的搜尋。

          搜尋所有 Salesforce 說明
          無周邊身分驗證 API:私人用戶端的授權代碼和認證流程

          無周邊身分驗證 API:私人用戶端的授權代碼和認證流程

          針對私人用戶端,例如用戶端-伺服器應用程式,您可以使用「授權代碼和認證流程」(建立於 OAuth 2.0 授權代碼授與類型),來為客戶和合作夥伴設定無周邊登入。

          必要版本

          提供版本:Salesforce Classic 與 Lightning Experience
          提供版本:EnterpriseUnlimitedDeveloper Edition
          備註
          備註 此時,第三方應用程式可參照 Salesforce 外部的任何應用程式。

          透過授權代碼與認證流程,您可以控制第三方應用程式的前端登入體驗。您透過 Experience Cloud 網站呼叫 Salesforce 無周邊登入 API 來處理驗證使用者,以及授與受保護 Salesforce 資源存取權的後端工作。透過分隔前端和後端流程,讓您的使用者直接登入及存取 Salesforce 資料,而無需離開應用程式。針對私人用戶端,您需要在瀏覽器中開始流程,並使用伺服器端回呼處理常式完成程式碼交換,以擷取授權代碼並將其交換為存取權杖。

          設定此流程前,請先完成下列步驟。

          由於您透過 Experience Cloud 網站管理 Salesforce Customer Identity,因此您只能針對使用 Experience Cloud 網站子網域 (例如 https://MyExperienceCloudSite.my.site.com) 的客戶和合作夥伴設定「授權代碼和認證流程」。針對使用 login.salesforce.com 或您組織特定的「我的網域」登入 URL 存取 Salesforce 平台的員工,或是存取 Experience Cloud 網站的員工,您無法設定此流程。

          以下是授權代碼和認證流程的範例使用個案。假設您任職於一間旅行公司,該公司將客戶資料儲存在 Salesforce 中。您已建立具有用戶端伺服器結構的自訂應用程式,並想讓使用者可在應用程式中存取過去的旅行預訂。您想同時完整控制登入體驗,以便與您公司的品牌化保持一致。因此,您需要將自訂應用程式設定為外部用戶端應用程式或連線的應用程式,並設定授權代碼和認證流程。

          依預設,使用者可輸入其使用者名稱以進行登入。若要提供使用者更多選項,請設定無周邊使用者探索。例如,開發流程讓使用者輸入其電子郵件地址、電話號碼,甚至是訂單號碼。請參閱 無周邊登入不含使用者名稱。

          以下是流程實際的簡化概觀。

          顯示具有備份伺服器 Web 應用程式授權代碼和認證流程的圖表
          • 當使用者前往您的自訂應用程式,應用程式內會內建顯示您的登入表單,讓使用者輸入其使用者名稱和密碼。或者,如果您使用無周邊使用者探索,他們會輸入電子郵件地址、電話號碼或訂單號碼等識別碼,以及其密碼。
          • 如果您是使用 Proof Key for Code Exchange (PKCE) 擴充功能,則應用程式會產生用於驗證授權代碼的值。如果您沒有使用 PKCE,則流程會略過此步驟。
          • 從瀏覽器中,自訂應用程式會透過 JavaScript 將無周邊授權代碼要求傳送至您 Experience Cloud 網站上的 Salesforce 無周邊登入 API 授權端點。
          • 如果您使用無周邊使用者探索,則您的 Apex 處理常式會根據使用者用於登入的識別碼尋找使用者。如果使用者認證有效,且使用者具有已驗證的電子郵件地址或電話號碼,則會繼續登入。
          • Salesforce 無周邊登入 API 會驗證使用者的認證,並將 302 重新導向傳回至包含授權代碼的預先設定 URL。在瀏覽器中處理 302 重新導向,並在伺服器上將回應無周邊傳遞給預先設定的回呼處理常式。
          • 伺服器端回呼處理常式會從 302 重新導向回應擷取授權程式碼和其他參數。接著會透過 Experience Cloud 網站權杖端點的伺服器端 POST 要求來起始程式碼交換。
          • 從權杖端點中,Salesforce 無周邊登入 API 會將存取權杖回應傳回給伺服器端回呼處理常式。
          • 伺服器端回呼處理常式會處理權杖回應,並將登入狀態傳回至應用程式。此回應可能包含工作階段詳細資料、使用者資訊,且可能包含存取權杖,視您的應用程式設計和安全性狀態而定。
          • 瀏覽器會接收登入回應,並建立使用者的工作階段。
          • 使用者現在已登入,且在您要求 Salesforce 資料的自訂應用程式中執行動作。例如,他們可以按一下按鈕來存取差旅預訂歷程記錄,該歷程記錄會儲存在 Salesforce Experience Cloud 網站中。
          • 您的自訂應用程式會向受保護的 Salesforce 端點 (例如 Salesforce API) 提出已驗證的要求。
          • 客戶現在可以在您的自訂應用程式中,存取自己受保護的資料。例如,他們可以查看自己的差旅預訂歷程記錄。

          此流程的一個重要元件是用戶端 JavaScript,此 JavaScript 會要求授權並接收存取權杖回應。此範例使用連線的應用程式。

          var clientId = '<Connected App Client ID>';
          var baseURL = '<Experience Cloud Domain>';
          var redirectURL = '<Experience Cloud Domain>/services/apexrest/code/exchange';
          
          function getUserInfo(accessToken, userInfoBaseURL) {
             var client = new XMLHttpRequest();
             client.open("GET", userInfoBaseURL + "/services/oauth2/userinfo", true);
             client.setRequestHeader("Content-Type", "application/json");
             client.setRequestHeader("Authorization", "Bearer " + accessToken);
             client.send();
             client.onreadystatechange = function() {
                 if(this.readyState == 3) {
                     response = JSON.parse(client.response);
                     response.access_token = accessToken;
                     document.getElementById("json").textContent = JSON.stringify(response, undefined, 2);
                     document.getElementById("results").style.display="block";
                 }
             }
          }
          
          function startLogin() {
             var username = document.getElementById('user_name').value;
             var password = document.getElementById('password').value;
             var encodedUNP = btoa(username + ':' + password);
             var client = new XMLHttpRequest();
             client.open("POST", baseURL + "/services/oauth2/authorize", true);
             client.setRequestHeader("Auth-Request-Type", "Named-User");
             client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
             client.setRequestHeader("Authorization", "Basic " + encodedUNP);
             client.send("response_type=code_credentials&client_id=" + clientId + "&redirect_uri=" + redirectURL);
             client.onreadystatechange = function() {
                 if(this.readyState == 3) {
                     console.log("here");
                     console.log(client.response);
                     response = JSON.parse(client.response);
                     if (response.success) {
                         getUserInfo(response.access_token, baseURL);
                     }
                 }
             }
             return false;
          }    
          

          另一個重要元件是伺服器端回呼處理常式,此處理常式會擷取程式碼並將其交換為存取權杖。以下是使用公開為 REST 資源之 Apex 類別的範例回呼處理常式。

          @RestResource(urlMapping='/code/exchange')
          global class CodeExchangeAPI {
            
             @HttpGet
             global static ExchangeResponse doGet() {
                 RestRequest req = RestContext.request;
                 RestResponse res = RestContext.response;
                 try {
                     res.statusCode = 200;
                    
                        String accessToken = doCodeExchange(req.params.get('code'), req.params.get('sfdc_community_url'));
                     if (accessToken != null) {
                          return new ExchangeResponse(accessToken, req.params.get('state'));
                     } else {
                         return new ExchangeResponse('Could not parse auth code redirect URI');
                     }
                 } catch (Exception e) {
                     res.statusCode = 500;
                     return new ExchangeResponse('Could not parse auth code redirect URI');
                 }
                
             }
            
            
             global static String doCodeExchange(String code, String communityURL) {
                 String clientId = 'Connected App Client ID';
                 String redirectURL = '<Experience Cloud Domain>/services/apexrest/code/exchange';
                 String clientSecret = null;
                
                 Http h = new Http();
                 HttpRequest req = new HttpRequest();
                 req.setMethod('POST');
                
                 //Create Code Exchange URL
                 String url = communityURL + '/services/oauth2/token';
                 req.setEndpoint(url);
                
                 //Post Body
                 String body = 'grant_type=authorization_code';
                 body = body + '&client_id=' + clientId;
                 body = body + '&code=' + code;
                 if (clientSecret != null) {
                    body = body + '&client_secret=' + clientSecret;
                 }
                 body = body + '&redirect_uri=' + redirectURL;
                
                 //URL encode Post Body
                 String encodedBody = EncodingUtil.urlEncode(body, 'UTF-8');
                
                 // Set request body
                 req.setBody(body);
                
                 //Add Headers
                 req.setHeader('Content-Type','application/x-www-form-urlencoded');
                
                 //Send Token Request
                 HttpResponse res = h.send(req);
                
                 if (res.getStatusCode() == 200) {
                     //Extract Token from Response
                     Map<String,Object> tokenResponseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
                     return (String)tokenResponseMap.get('access_token');
                 } else {
                     return null;
                 }
             }
            
             // Response Wrapper
             global class ExchangeResponse {
                 String access_token;
                 String state;
                 String errMsg;
                 Boolean success; 
                
                 public ExchangeResponse(String access_token, String state) {
                     this.access_token = access_token;
                     this.state = state;
                     this.success = true;
                 }
                
                  public ExchangeResponse(String errMsg) {
                     this.success = false;
                     this.errMsg = this.errMsg;
                 }       
             }
          }
          

          以下是此流程的詳細細目。

          一般使用者開啟第三方應用程式並登入

          您的使用者開啟第三方應用程式並準備登入。您的應用程式中會顯示登入表單,其中包含使用者名稱、密碼欄位和登入按鈕。Salesforce 不會提供此登入表單。表單的外觀與風格由您決定。您的使用者會輸入其使用者名稱與密碼,並按一下登入按鈕。

          第三方應用程式產生 code_verifiercode_challenge 值 (選擇性)

          如果您是使用 Proof Key for Code Exchange (PKCE) 擴充功能,則應用程式會產生用於驗證授權代碼的值。

          根據安全性的最佳作法,我們強烈建議在實作授權代碼和認證流程時使用 PKCE 擴充功能。如需 PKCE 的詳細資訊,請參閱由 網際網路工程任務小組 (IETF) 提供的規格RFC 7636: Proof Key for Code Exchange by OAuth Public Clients

          RFC 7636 中定義的 PKCE 規格也包含可在授權要求中傳送的選用 code_challenge_method 參數。Salesforce 會忽略您在此參數中傳送的任何值,並預設為 SHA256

          當您使用伺服器端回呼處理常式實作此流程時,請在連線的應用程式中啟用「需要 Web 伺服器流程的密碼」與「需要重新整理權杖流程的密碼」設定。啟用這些設定後,請確保您的回呼處理常式會保護取用者密碼的安全性。

          第三方應用程式無周邊要求的授權代碼

          從瀏覽器中,第三方應用程式會使用非同步 Java 與 XML (AJAX) 將無周邊授權要求傳送至 Experience Cloud 網站上的無周邊登入 API 授權端點。如果您未使用無周邊使用者探索,您可以針對此要求使用 GET 或 POST 方法。如果您使用無周邊使用者探索,則僅支援 POST 要求。

          在此用戶端 JavaScript 範例中,startLogin 函數會無周邊將 POST 要求傳送至授權端點。

          function startLogin() {
             var username = document.getElementById('user_name').value;
             var password = document.getElementById('password').value;
             var encodedUNP = btoa(username + ':' + password);
             var client = new XMLHttpRequest();
             client.open("POST", baseURL + "/services/oauth2/authorize", true);
             client.setRequestHeader("Auth-Request-Type", "Named-User");
             client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
             client.setRequestHeader("Authorization", "Basic " + encodedUNP);
             client.send("response_type=code_credentials&client_id=" + clientId + "&redirect_uri=" + redirectURL);
             client.onreadystatechange = function() {
                 if(this.readyState == 3) {
                     console.log("here");
                     console.log(client.response);
                     response = JSON.parse(client.response);
                     if (response.success) {
                         getUserInfo(response.access_token, baseURL);
                     }
                 }
             }
             return false;
          }  

          針對 GET 與 POST 要求,您必須包含標題 Auth-Request-Type: Named-User

          或者,若要將此流程連線至無周邊來賓流程,您可以包含具有 JWT 型存取權杖的 Uvid-Hint 標頭,其中包含 UVID 值,這是完全由應用程式產生和管理的第 4 版通用唯一識別碼 (UUID)。若要取得具有 UVID 的存取權杖,您必須啟用外部用戶端應用程式來核發 JWT 型存取權杖,並在應用程式上實作無周邊來賓流程。

          否。如果您在應用程式上實作來賓使用者流程,您可以選擇性使用此標頭傳遞 JSON Web 權杖 (JWT) 型存取權杖,其中包含與來賓使用者身分繫結的唯一訪客識別碼 (UVID)。透過將 UVID 傳遞給已命名使用者流程,您可以將來自來賓使用者工作階段的內容資訊 (例如使用者的 Cookie 偏好設定) 帶入至已命名使用者工作階段。

          您也可以在要求內文中包含 UVID 純文字值。

          根據您使用的方法和組態,有時您需要包含具有使用者認證的「基本」類型授權標題。如果您使用 GET 要求,則必須以授權標頭傳送使用者的認證 (使用者名稱和密碼,相互附加並以 Base64 編碼)。以下是範例 GET 要求。

          GET /services/oauth2/authorize? HTTP 1.1
          Host: MyDomainName.my.site.com
          Auth-Request-Type: Named-User
          Authorization: Basic <encoded username:password>
          
          response_type=code_credentials&
          redirect_uri=https://www.MyDomainName.my.site.com/services/apexrest/code/exchange&
          client_id=******&
          code_challenge=Y29kZ*******

          如果您使用 POST 要求,可以將 Base64 編碼的使用者認證包含在授權標頭,也可以將其放在要求內文中。

          如果您使用無周邊使用者探索,則不會傳送使用者名稱和密碼。您會改為在 login_hint 參數中傳送識別碼、選擇性自訂資料和密碼。在 POST 要求內文中包含識別碼、自訂資料和密碼。請勿使用 GET 要求。

          備註
          備註 如果已在外部用戶端應用程式或連線應用程式上啟用「授權代碼和認證流程的 POST 內文中需要使用者認證」設定,則您只能在要求內文中傳送使用者認證。啟用此設定後,您便無法針對授權代碼要求使用 GET 方法。您只能使用 POST 方法。

          針對 GET 與 POST 方法,請在授權要求的內文中包含這些必要參數。

          參數描述
          client_id 外部用戶端應用程式或連線應用程式的取用者金鑰。
          redirect_uri

          在成功驗證後,將使用者重新導向至其中的 URL。重新導向 URI 必須與外部用戶端應用程式「回呼 URL」欄位中的其中一個值相符。否則批准會失敗。

          針對私人用戶端,請使用指向伺服器端回呼處理常式的 redirect_uri。例如,指向 Apex REST 程式碼交換端點,例如 <Experience Cloud Domain>/services/apexrest/code/exchange

          response_type 應用程式要求的 OAuth 2.0 授與類型。針對「授權代碼和認證流程」,此值必須為 code_credentials

          您也可以在授權要求中包含下列選用參數。

          參數描述
          code_challenge

          使用 PKCE 擴充功能時為必要。指定權杖要求中 code_verifier 值的 SHA256 雜湊值。設定此參數來協助避免授權代碼攔截攻擊。此值必須如 https://tools.ietf.org/html/rfc4648#section-5 中定義的方式以 base64url 編碼。

          如果在權杖要求中指定 code_verifier,則需要此參數。

          • 如果授權要求中提供 code_challenge 值,且權杖要求中提供 code_verifier 值,則 Salesforce 會將 code_challengecode_verifier 比較。如果 code_challenge 無效或不相符,則登入會失敗並顯示 invalid_request 錯誤碼。
          • 如果授權要求中提供 code_challenge 值,但權杖要求中未提供 code_verifier 值,則登入會失敗並顯示 invalid_grant 錯誤碼。
          scope 權限,其會定義外部用戶端應用程式或連線應用程式可存取的受保護資源類型。您在建立連線的應用程式時將範圍指派至其中,且在授權流程期間這些範圍會隨附 OAuth 權杖。若您並未包含此參數,則會要求指派給應用程式的全部範圍。若要進一步限制範圍,請在此參數中傳遞指派範圍的子集。如需有效的參數,請參閱 OAuth 範圍
          state 外部 Web 服務要求傳送至回呼 URL 的任何狀態。這個值必須經過 URL 編碼。
          uvid_hint

          純文字 UVID 值,這是完全由應用程式產生及管理的版本 4 UUID。若要取得 UVID,您必須啟用應用程式來核發 JWT 型存取權杖,並在應用程式上實作無周邊來賓流程。您可以選擇性使用此參數傳遞與來賓使用者身分繫結的 UVID 值,將來賓使用者工作階段中的內容資訊帶入已命名使用者工作階段。

          您也可以透過 UVID-Hint 標頭,以 JWT 型權杖傳遞 UVID,而不是在要求內文中傳遞 UVID。

          login_hint 使用無周邊使用者探索時為必要。您的 Apex 處理常式用來尋找使用者 Salesforce 帳戶的識別碼。例如,在應用程式中收集使用者的訂單編號,並在 login_hint 參數中傳遞。我們會將 login_hint 值直接傳送至您的 Apex 處理常式。
          customdata

          如果您使用處理自訂資料的無周邊使用者探索處理常式,則為必要。例如,如果您同時將處理常式與處理自訂資料的登入流程搭配使用,則必須在忘記密碼流程中傳遞自訂資料。

          包含 Apex 無周邊探索處理常式用來尋找使用者 Salesforce 帳戶之其他資料的 JSON 字串。例如,傳遞使用者地區設定的相關資訊。

          (選用) 無周邊使用者探索處理常式尋找使用者

          如果您使用無周邊使用者探索處理常式,則處理常式會取得 login_hintcustomdata 參數,並尋找相關聯的使用者。處理常式會確認使用者的電子郵件地址或電話號碼已驗證。

          如需範例處理常式,請參閱 Auth.HeadlessUserDiscoveryHandler

          Salesforce 驗證認證並傳回 302 重新導向

          Salesforce 無周邊登入 API 會驗證使用者和應用程式的認證,並將 HTTP 302 重新導向傳回至包含授權代碼的預先設定 URL。在瀏覽器中處理 302 重新導向,並將回應無周邊傳送至重新導向 URL,這是您伺服器上預先設定的回呼端點。範例 URL 如下。

          https://www.MyDomainName.my.site.com/services/apexrest/code/exchange?code=aPrxC1*******
          &sfdc_community_url=https%3A%2F%2FMyDomainName.my.site.com&sfdc_community_id=0DBxxxxxxxxxxxx
          

          回呼處理常式會擷取程式碼並執行程式碼交換

          伺服器端回呼處理常式會從 302 重新導向中擷取授權代碼和其他參數。接著會透過將無周邊 POST 要求傳送至權杖端點來啟動程式碼交換。

          在範例 Apex REST 回呼處理常式中,doGet 方法會 ⁇ 取程式碼。

          @RestResource(urlMapping='/code/exchange')
          global class CodeExchangeAPI {
            
             @HttpGet
             global static ExchangeResponse doGet() {
                 RestRequest req = RestContext.request;
                 RestResponse res = RestContext.response;
                 try {
                     res.statusCode = 200;
                    
                        String accessToken = doCodeExchange(req.params.get('code'), req.params.get('sfdc_community_url'));
                     if (accessToken != null) {
                          return new ExchangeResponse(accessToken, req.params.get('state'));
                     } else {
                         return new ExchangeResponse('Could not parse auth code redirect URI');
                     }
                 } catch (Exception e) {
                     res.statusCode = 500;
                     return new ExchangeResponse('Could not parse auth code redirect URI');
                 }
                
             }
          

          接著,doCodeExchange 方法會傳送權杖要求。

          global static String doCodeExchange(String code, String communityURL) {
                 String clientId = 'Connected App Client ID';
                 String redirectURL = '<Experience Cloud Domain>/services/apexrest/code/exchange';
                 String clientSecret = '<ConnecedApp Secret>';
                
                 Http h = new Http();
                 HttpRequest req = new HttpRequest();
                 req.setMethod('POST');
                
                 //Create Code Exchange URL
                 String url = communityURL + '/services/oauth2/token';
                 req.setEndpoint(url);
                
                 //Post Body
                 String body = 'grant_type=authorization_code';
                 body = body + '&client_id=' + clientId;
                 body = body + '&code=' + code;
                 if (clientSecret != null) {
                    body = body + '&client_secret=' + clientSecret;
                 }
                 body = body + '&redirect_uri=' + redirectURL;
                
                 //URL encode Post Body
                 String encodedBody = EncodingUtil.urlEncode(body, 'UTF-8');
                
                 // Set request body
                 req.setBody(body);
                
                 //Add Headers
                 req.setHeader('Content-Type','application/x-www-form-urlencoded');
                
                 //Send Token Request
                 HttpResponse res = h.send(req);
                
                 if (res.getStatusCode() == 200) {
                     //Extract Token from Response
                     Map<String,Object> tokenResponseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
                     return (String)tokenResponseMap.get('access_token');
                 } else {
                     return null;
                 }
             }
          

          針對存取權杖要求,您只能使用 POST 要求—不支援 GET 要求。您必須包含 Content-Type 標題。在要求內文中包含這些必要參數。

          參數描述
          client_id 外部用戶端應用程式或連線應用程式的取用者金鑰。
          client_secret 外部用戶端應用程式或連線應用程式的取用者密碼。
          code 授權伺服器會在成功驗證後建立授權代碼,並將其傳遞至用戶端,該授權代碼為短暫的權杖。用戶端會將授權代碼傳送至授權伺服器來取得存取權杖,或者是重新整理權杖。
          grant_type 應用程式可以提供用來證明其是安全訪客的驗證類型。針對「授權代碼和認證流程」,此值必須是 authorization_code
          redirect_uri

          在成功驗證後,將使用者重新導向至其中的 URL。重新導向 URI 必須與「回呼 URL」欄位中的其中一個值相符。否則批准會失敗。這個值必須經過 URL 編碼。

          針對私人用戶端,請使用指向伺服器端回呼處理常式的 redirect_uri。例如,指向 Apex REST 程式碼交換端點,例如 <Experience Cloud Domain>/services/apexrest/code/exchange

          您也可以在權杖要求中包含下列選用參數。

          參數描述
          code_verifier

          使用 PKCE 擴充功能時為必要。指定具有高 ⁇ 度的 128 位元組隨機資料,以難以猜出 code 值。設定此參數來協助避免授權代碼攔截攻擊。此值必須如 https://tools.ietf.org/html/rfc4648#section-5 中定義的方式以 base64url 編碼。

          • 如果授權要求中提供 code_verifier 值,而權杖要求中包含 code_challenge 值,Salesforce 會比較 code_verifiercode_challenge。如果 code_verifier 無效或不符合,則登入會失敗並顯示 invalid_grant 錯誤碼。
          • 如果權杖要求中提供 code_verifier 值,但授權要求中未提供 code_challenge 值,則登入會失敗並顯示 invalid_grant 錯誤碼。
          format

          回應的預期格式。Salesforce 支援這些格式。

          • urlencoded
          • json (預設值)
          • xml

          在 Apex 程式碼中,回應包裝程式會設定最終傳回應用程式的變數,包括成功與錯誤指標。

           // Response Wrapper
             global class ExchangeResponse {
                 String access_token;
                 String state;
                 String errMsg;
                 Boolean success; 
                
                 public ExchangeResponse(String access_token, String state) {
                     this.access_token = access_token;
                     this.state = state;
                     this.success = true;
                 }
                
                  public ExchangeResponse(String errMsg) {
                     this.success = false;
                     this.errMsg = this.errMsg;
                 }       
             }

          Salesforce 授與存取權杖

          Salesforce 無周邊登入 API 會接收權杖要求,並將存取權杖回應傳回至伺服器端回呼處理常式。以下是 JSON 格式的範例存取權杖回應。

          {
          "access_token":"*******************",
          "sfdc_community_url":"https://MyDomainName.my.site.com",
          "sfdc_community_id":"0DBxxxxxxxxxxxx",
          "signature":"ts6wm/svX3jXlCGR4uu+SbA04M6qhD1SAgVTEwZ59P4=",
          "scope":"openid api",
          "id_token":"XXXXXX",
          "instance_url":"https://yourInstance.salesforce.com",
          "id":"https://yourInstance.salesforce.com/id/00Dxxxxxxxxxxxx/005xxxxxxxxxxxx",
          "token_type":"Bearer",
          "issued_at":"1667600739962"
          }

          存取權杖回應包含以下必要參數。

          參數 描述
          access_token OAuth 權杖,外部用戶端應用程式或連線應用程式會使用此權杖來代表用戶端應用程式,要求對受保護資源的存取權。範圍格式的其他權限可能會隨附存取權杖。
          id 身分 URL,此 URL 可用來識別使用者與查詢使用者的詳細資訊。請參閱身分 URL
          instance_url 指示使用者組織例項的 URL。例如:https://yourInstance.salesforce.com/.
          issued_at 建立簽章時的時間戳記,表示為從 1970-01-01T0:0:0Z UTC 開始的毫秒數。
          signature client_secret 簽署的 Base64 編碼 HMAC-SHA256 簽章。簽章可以包含串連的識別碼和 issued_at value,您可以用來確認身分 URL 自伺服器傳送後未變更。
          sfdc_community_url Experience Cloud 網站的 URL。
          sfdc_community_id 使用者的 Experience Cloud 網站識別碼。
          token_type Bearer 權杖類型,用於包含存取權杖的所有回應。

          存取權杖回應也可能包含以下參數。

          參數 描述
          id_token

          包含經驗證使用者屬性的已簽署資料結構,屬性內含使用者的唯一識別碼,以及指示權杖核發時間的時間戳記。此權杖也會識別提出要求的用戶端應用程式。請參閱 OpenID Connect 規格

          如果 scope 參數包含 openid,則會傳回此參數。

          refresh_token 從 Web 伺服器、使用者代理程式或混合式應用程式權杖流程所取得的權杖。這個值是密碼。採取適當的措施來保護此值。只有在您的外部用戶端應用程式或連線應用程式設定為具有 refresh_token 範圍時,才會傳回此參數。
          state 用戶端所要求的狀態。只有在原始查詢字串中包含 state 參數時,才會包含此值。

          回呼處理常式會處理權杖回應,並將參數傳回給應用程式

          伺服器端回呼處理常式會從回應取得存取權杖。在伺服器端 Apex 程式碼範例中,此程序會在 doCodeExchange 方法中進行,作為傳送權杖要求的一部分。

          //Send Token Request
                 HttpResponse res = h.send(req);
                
                 if (res.getStatusCode() == 200) {
                     //Extract Token from Response
                     Map<String,Object> tokenResponseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
                     return (String)tokenResponseMap.get('access_token');
                 } else {
                     return null;
                 }
          

          伺服器端回呼處理常式會將存取權杖和狀態連同使用者資料、權杖和工作階段資料一起傳回至瀏覽器。在此範例中,回應包裝程式會將存取權杖傳回給應用程式。作為最佳作法,建議您設定伺服器來儲存存取權杖、建立應用程式的工作階段,並將工作階段 (而非存取權杖) 傳回應用程式。身為開發人員,您擁有建立工作階段、儲存存取權杖及管理登入狀態的完整控制權,因此您的特定實作由您自行決定。

          以下是瀏覽器主控台記錄中成功回應的範例。

          {"success":true,"state":"https://MyExperienceCloudSite.my.site.com/","errMsg":null,"access_token":"00*******"}

          應用程式處理權杖回應並建立使用者工作階段

          應用程式會接收權杖回應、進行處理,並建立使用者工作階段。在用戶端 JavaScript 範例中,會透過 getUserInfo 函數處理回應。

          function getUserInfo(accessToken, userInfoBaseURL) {
             var client = new XMLHttpRequest();
             client.open("GET", userInfoBaseURL + "/services/oauth2/userinfo", true);
             client.setRequestHeader("Content-Type", "application/json");
             client.setRequestHeader("Authorization", "Bearer " + accessToken);
             client.send();
             client.onreadystatechange = function() {
                 if(this.readyState == 3) {
                     response = JSON.parse(client.response);
                     response.access_token = accessToken;
                     document.getElementById("json").textContent = JSON.stringify(response, undefined, 2);
                     document.getElementById("results").style.display="block";
                 }
             }
          }
          

          一般使用者已登入並在應用程式中執行動作

          您的使用者現在已登入。他們在您的應用程式中執行需要存取 Salesforce 資料的動作。例如,他們按一下按鈕以檢視其儲存在 Salesforce 中的差旅預訂歷程記錄。

          備註
          備註 當您為授權代碼和認證流程設定外部用戶端應用程式或連線應用程式時,您需要將「允許的使用者」原則設為「管理員批准的使用者均獲得預先授權」,並設定可存取應用程式的設定檔或權限集。在此原則下,使用者可在無授權的情況下存取應用程式,因此系統不會提示授權畫面,即可讓應用程式存取他們的資料。

          應用程式對 Salesforce 端點發出已驗證的呼叫

          為存取使用者的 Salesforce 資料,您的應用程式會使用存取權杖來對受保護的 Salesforce 端點 (例如 Salesforce API) 進行驗證呼叫。

          一般使用者存取 Salesforce 資料

          使用者現在可以存取應用程式中的受保護 Salesforce 資料。例如,他們可以查看自己的差旅預訂歷程記錄。對一般使用者來說,從登入到存取其資料的整個流程,他們都無須離開應用程式。

           
          正在載入
          Salesforce Help | Article