Loading
メールアドレスがデフォルトのログイン方式となります 続きを読む
ユーザーの識別およびアクセス権の管理
ヘッドレス ID API: 公開クライアントの認証コードとログイン情報フロー

ヘッドレス ID API: 公開クライアントの認証コードとログイン情報フロー

単一ページアプリケーションやモバイルアプリケーションなどの公開クライアントの場合、認証コードとログイン情報フローを使用して、顧客とパートナーのヘッドレスログインを設定できます。このフローは、OAuth 2.0 認証コード許可種別に基づいて構築されています。認証コードとログイン情報フローを使用すると、サードパーティアプリケーションのフロントエンドのログイン環境を制御できます。Experience Cloud サイトを介して Salesforce ヘッドレスログイン API をコールし、ユーザーを認証して、保護されている Salesforce リソースへのアクセス権を付与するバックエンド作業を処理します。別個のフロントエンドとバックエンドのプロセスにより、ユーザーはアプリケーションから離れることなくログインして Salesforce データにアクセスできます。単一ページアプリケーションの場合、サーバー側コールバックエンドポイントを使用して認証コードを抽出し、クライアント側の JavaScript を介してブラウザーからコード交換を実行します。

必要なエディション

使用可能なインターフェース: Salesforce Classic および Lightning Experience の両方
使用可能なエディション: Enterprise Edition、Unlimited Edition、および Developer Edition
警告
警告 セキュリティ上の理由により、可能な限りこのフローのクライアントとサーバーのバリエーションを常に使用することを強くお勧めします。クライアント-サーバーのバリエーションにより、コード交換中にコンシューマーの秘密に関する保護が強化されます。詳細は、「ヘッドレス ID API: 非公開クライアントの認証コードとログイン情報フロー」を参照してください。
メモ
メモ ここでは、サードパーティアプリケーションとは Salesforce 外部のアプリケーションを指します。

このヘルプコンテンツでは、フローの設定方法とその機能について説明します。エンドツーエンドのサンプル実装を設定するには、『Headless Identity Implementation Guide (ヘッドレス ID 実装ガイド)』を参照してください。

このフローを設定する前に、次の手順を実行します。

Salesforce Customer Identity は Experience Cloud サイトを通じて管理するため、認証コードとログイン情報フローは、https://MyExperienceCloudSite.my.site.com など Experience Cloud サイトのサブドメインを使用している顧客やパートナーのみに設定できます。このフローは、login.salesforce.com または組織固有の [私のドメイン] ログイン URL を使用して Salesforce プラットフォームにアクセスする従業員や Experience Cloud サイトにアクセスする従業員には設定できません。

認証コードとログイン情報フローの使用事例を次に示します。あなたは顧客データを Salesforce に保存している旅行会社に勤務しています。カスタム単一ページアプリケーションを作成し、ユーザーがアプリケーションから過去の旅行予約にアクセスできるようにしたいと考えています。さらに、会社のブランド設定に合わせてログイン環境を完全に制御できるようにしたいと考えています。そこで、カスタムアプリケーションを外部クライアントアプリケーションまたは接続アプリケーションとして設定し、認証コードとログイン情報フローを設定します。

デフォルトでは、ユーザーはユーザー名を入力してログインします。ユーザーにその他のオプションを提供するには、ヘッドレスユーザー検出を設定します。たとえば、ユーザーがメールアドレス、電話番号、または注文番号を入力するフローを作成します。「ユーザー名なしのヘッドレスログイン」を参照してください。

実際のフローを簡略化した概要を次に示します。

単一ページアプリケーションの認証コードとログイン情報フローが表示されている図
  • ユーザーがカスタムアプリケーションに移動します。ログインフォームがアプリケーション内にネイティブに表示され、ユーザー名とパスワードを入力します。または、ヘッドレスユーザー検出を使用している場合は、メールアドレス、電話番号、注文番号などの識別子をパスワードと共に入力します。
  • コード交換の証明鍵 (PKCE) 拡張機能を使用している場合、認証コードを検証する値がアプリケーションによって生成されます。PKCE を使用していない場合、このステップはスキップされます。単一ページアプリケーションにこのフローを実装する場合は、常に PKCE を使用することを強くお勧めします。
  • ブラウザーから、カスタムアプリケーションが JavaScript を介して Experience Cloud サイト上の Salesforce ヘッドレスログイン API 認証エンドポイントにヘッドレス認証要求を送信します。
  • ヘッドレスユーザー検出を使用している場合、Apexハンドラーはログインに使用した識別子に基づいてユーザーを検索します。ユーザーのログイン情報が有効で、ユーザーが検証済みのメール・アドレスまたは電話番号を持っている場合、ログインが続行されます。
  • Salesforce ヘッドレスログイン API がユーザーのログイン情報を検証し、認証コードを含む事前設定された URL に HTTP 302 リダイレクトを返します。次に、Salesforce が自動的にリダイレクト応答をリダイレクト URL に送信します。この URL はサーバー側コールバックハンドラーを指し示します。
  • サーバー側コールバックハンドラーが 302 リダイレクトから認証コードを抽出し、アプリケーションに返します。
  • クライアント側の JavaScript がリダイレクト URL パラメーターを受信し、トークンエンドポイントへの POST 要求でコード交換を開始します。
  • Salesforce ヘッドレスログイン API が要求を検証し、アクセストークン応答をアプリケーションに返します。
  • アプリケーションのクライアント側の JavaScript がアクセストークンを処理し、ユーザーのセッションを作成します。
  • ユーザーはログイン状態になり、Salesforce データの要求を開始するアクションをカスタムアプリケーションで実行します。たとえば、Salesforce Experience Cloud サイトに保存されている旅行予約履歴にアクセスするボタンをクリックします。
  • カスタムアプリケーションが Salesforce API などの保護された Salesforce エンドポイントに認証された要求を行います。
  • ユーザーはカスタムアプリケーションで、保護されているデータにアクセスできるようになりました。たとえば、旅行予約履歴を表示できます。

このフローの主要コンポーネントは、認証要求を送信し、コード交換を実行してアクセストークンを処理するクライアント側の JavaScript です。接続アプリケーションを使用する JavaScript の例を次に示します。

var clientId = "<Connected App Client ID>";
var baseURL = "<Experience Cloud Domain>";
var redirectURL = "<Experience Cloud Domain>/services/apexrest/code/extraction"
      
// Performs the code exchange
function doCodeExchange(authorizeResponse) {
   //Perform Code Exchange
   //Get Access Token
   var client = new XMLHttpRequest();
   client.open("POST", authorizeResponse.sfdc_community_url + "/services/oauth2/token", true);
   client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   client.send("code=" + authorizeResponse.code + "&grant_type=authorization_code&client_id=" + clientId + "&redirect_uri=" + redirectURL);
   client.onreadystatechange = function() {
       if(this.readyState == 3) {
           response = JSON.parse(client.response);
           getUserInfo(response.access_token, response.sfdc_community_url)
       }
   }
}

// Gets User Info
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";
       }
   }
}

//Starts the Login Process
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) {
           response = JSON.parse(client.response);
           doCodeExchange(response);
       }
   }
   return false;
}    

別の主要コンポーネントは、302 リダイレクトからコードを抽出し、アプリケーションに返すサーバー側コールバックハンドラーです。この例では、ハンドラーは公開 REST エンドポイントとして公開される Apex クラスであり、クロスオリジンリソース共有 (CORS) が有効で、クロスサイトスクリプティング保護を提供しています。開発を簡略化するには、OAuth 2.0 エコーエンドポイントを使用して認証コードを取得します。

@RestResource(urlMapping='/code/extraction')
global class CodeExtractorAPI {
  
   @HttpGet
   global static CodeResponse doGet() {
       RestRequest req = RestContext.request;
       RestResponse res = RestContext.response;
       try {
           res.statusCode = 200;
           return new CodeResponse(req.params.get('code'), req.params.get('sfdc_community_url'), req.params.get('sfdc_community_id'), req.params.get('state'));
       } catch (Exception e) {
           res.statusCode = 500;
           return new CodeResponse('Could not parse auth code redirect URI');
       }
      
   }
  
   // Response Wrapper
   global class CodeResponse {
       String code;
       String sfdc_community_url;
       String sfdc_community_id;
       String state;
       Boolean success;
       String errMsg;
      
       public CodeResponse(String code, String sfdc_community_url, String sfdc_community_id, String state) {
           this.code = code;
           this.sfdc_community_url = sfdc_community_url;
           this.sfdc_community_id = sfdc_community_id;
           this.state = state;
           this.success = true;
       }
      
        public CodeResponse(String errMsg) {
           this.success = false;
           this.errMsg = this.errMsg;
       }       
   }
}

このフローの詳細な内訳は次のようになります。

エンドユーザーがサードパーティアプリケーションを開いてログインする

ユーザーが、ログインに使用するサードパーティアプリケーションを開きます。このアプリケーションには、ユーザー名項目、パスワード項目、ログインボタンを含むログインフォームが表示されます。Salesforce はこのログインフォームを提供していません。お客様が自由にデザインできます。ユーザーはユーザー名とパスワードを入力して、ログインボタンをクリックします。

サードパーティアプリケーションによる code_verifier 値および code_challenge 値の生成 (省略可能)

コード交換の証明鍵 (PKCE) 拡張機能を使用している場合、認証コードの検証に使用する値がアプリケーションによって生成されます。

このステップは、コード交換の証明鍵 (PKCE) 拡張機能を使用している場合にのみ含まれます。セキュリティのベストプラクティスとして、特に単一ページアプリケーションで認証コードとログイン情報フローを実装する場合は、PKCE 拡張機能を使用することを強くお勧めします。PKCE についての詳細は、Internet Engineering Task Force (IETF) が提供する仕様「RFC 7636: Proof Key for Code Exchange by OAuth Public Clients (OAuth 公開クライアントによるコード交換の証明鍵)」を参照してください。

RFC 7636 で定義された PKCE 仕様には、認証要求で送信できる、省略可能な code_challenge_method パラメーターも含まれています。このパラメーターで送信する値は、Salesforce では無視され、デフォルトの SHA256 になります。

サードパーティアプリケーションが認証コードをヘッドレスで要求する

ブラウザーから、カスタムアプリケーションが JavaScript を介して Salesforce ヘッドレスログイン API 認証エンドポイントにヘッドレス認証コード要求を送信します。ヘッドレスユーザー検出を使用していない場合、この要求で GET または POST メソッドを使用します。ヘッドレスユーザー検出を使用している場合、POST 要求のみがサポートされます。

このクライアント側の JavaScript 抜粋では、startLogin 関数の一部として認証要求が送信されています。ユーザーのログイン情報を取得したら、この関数はサーバー側コールバックハンドラーを指し示すリダイレクト URL を含む 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 を含める必要があります。

使用するメソッドと外部クライアントアプリケーションまたは接続アプリケーションの設定によっては、ユーザーのログイン情報を含む Basic 種別の認証ヘッダーを含めなければならない場合があります。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.MyExperienceCloudSite.my.site.com/services/apexrest/code/extraction&
client_id=******&
code_challenge=Y29kZ*******

POST 要求を使用する場合は、Base64 でエンコードされたユーザーログイン情報を認証ヘッダーに含めるか、リクエストボディに入力することができます。

ヘッドレスユーザー検出を使用している場合、ユーザー名とパスワードは送信しません。代わりに、login_hint パラメーター内の識別子、省略可能なカスタムデータ、およびパスワードを送信します。POST 要求の本文にその識別子、カスタムデータ、パスワードを含めます。GET 要求は使用しないでください。

必要に応じて、このフローをヘッドレスゲストフローに接続するには、UVID 値が含まれる JWT ベースのアクセストークンがある Uvid-Hint ヘッダーを含めます。これは、アプリケーションによって生成されて完全に管理されるバージョン 4 のユニバーサル一意識別子 (UUID) です。UVID でアクセストークンを取得するには、JWT ベースのアクセストークンを発行し、アプリケーションでヘッドレスゲストフローを実装できるように外部クライアントアプリケーションまたは接続アプリケーションを有効にする必要があります。

アプリケーションでゲストユーザーフローを実装する場合、必要に応じてこのヘッダーを使用して、ゲストユーザーの ID に関連付けられた一意の訪問者 ID (UVID) が含まれる JSON Web トークン (JWT) ベースのアクセストークンを渡すことができます。UVID を指定ユーザーフローに渡すことで、ゲストユーザーセッションから指定ユーザーセッションにユーザーの Cookie 設定などのコンテキスト情報を伝達できます。

リクエストボディにプレーン UVID 値を含めることもできます。

メモ
メモ 外部クライアントアプリケーションまたは接続アプリケーションで [認証コードおよびログイン情報フローの POST 本文でユーザーログイン情報を要求] 設定が有効になっている場合、ユーザーログイン情報はリクエストボディでのみ送信できます。この設定を有効にすると、認証コード要求に GET メソッドは使用できません。POST メソッドのみを使用できます。

GET メソッドと POST メソッドの両方で、認証要求の本文に次の必須パラメーターを含めます。

パラメーター説明
client_id 外部クライアントアプリケーションまたは接続アプリケーションのコンシューマー鍵。
redirect_uri

認証に成功した後にユーザーがリダイレクトされる URL。リダイレクト URI は、外部クライアントアプリケーションまたは接続アプリケーションの [コールバック URL] 項目の値のいずれかと一致する必要があります。それ以外の場合、承認は失敗します。

公開クライアントの場合、リダイレクト URI は Salesforce からの 302 リダイレクトを処理できるエンドポイントを参照する必要があります。開発を簡略化するには、https://MyExperienceCloudSite.my.site.com/services/oauth2/echo などの OAuth エコーエンドポイントを使用します。

次の例では、Apex REST コード抽出エンドポイントを使用しています。たとえば、<Experience Cloud Domain>/services/apexrest/code/extraction です。

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_challenge と code_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 ベースのアクセストークンを発行し、アプリケーションにヘッドレスゲストフローを実装できるように外部クライアントアプリケーションまたは接続アプリケーションを有効にする必要があります。必要に応じてこのパラメーターを使用して、ゲストユーザーの ID に関連付けられた UVID 値を渡し、ゲストユーザーセッションから指定ユーザーセッションにコンテキスト情報を伝達できます。

リクエストボディで UVID を渡す代わりに、UVID-Hint ヘッダーを使用して UVID が含まれる JWT ベースのトークンを渡すこともできます。

login_hint ヘッドレスユーザー検出を使用している場合は必須です。Apex ハンドラーがユーザーの Salesforce アカウントを検索するために使用する識別子。たとえば、アプリケーションでユーザーの注文番号を収集し、login_hint パラメーターに渡します。login_hint 値が Apex ハンドラーに直接送信されます。
customdata

カスタムデータを処理するヘッドレスユーザー検出ハンドラーを使用している場合は必須です。たとえば、カスタムデータを処理するログインフローでもハンドラーを使用している場合、パスワードを忘れた場合のフローでカスタムデータを渡す必要があります。

Apex ヘッドレス検出ハンドラーがユーザーの Salesforce アカウントを検索するために使用する追加データを含む JSON 文字列。たとえば、ユーザーのロケールに関する情報を渡します。

(省略可能) ヘッドレスユーザー検出ハンドラーによるユーザーの検索

ヘッドレスユーザー検出ハンドラを使用している場合、ハンドラは login_hint パラメーターと customdata パラメーターを使用して、関連付けられたユーザーを検索します。ハンドラーは、ユーザーのメールアドレスまたは電話番号が検証されていることを確認します。

ハンドラの例については、「Auth.HeadlessUserDiscoveryHandler」を参照してください。

Salesforce がログイン情報を検証して、サーバー側コールバックハンドラーに 302 リダイレクトを返す

Salesforce ヘッドレスログイン API が認証要求を受け取ります。ユーザーのログイン情報を検証し、認証コードを含む事前設定された URL に 302 リダイレクトを返します。次に、Salesforce が自動的にリダイレクト応答をリダイレクト URL に送信します。この URL は、この例では /code/extraction エンドポイントにあるサーバー側コールバックハンドラーを指し示します。このプロセス中、ブラウザーはリダイレクトされません。すべてがバックグラウンドで行われます。

サーバー側コールバックハンドラーがコードを抽出してアプリケーションに返す

サーバー側コールバックハンドラーが認証コードおよびその他のデータを抽出します。この例の Apex コールバックハンドラーでは、doGet メソッドを使用して、302 リダイレクトからコード、Experience Cloud サイト URL、サイト ID、状態を抽出します。

@RestResource(urlMapping='/code/extraction')
global class CodeExtractorAPI {
  
   @HttpGet
   global static CodeResponse doGet() {
       RestRequest req = RestContext.request;
       RestResponse res = RestContext.response;
       try {
           res.statusCode = 200;
           return new CodeResponse(req.params.get('code'), req.params.get('sfdc_community_url'), req.params.get('sfdc_community_id'), req.params.get('state'));
       } catch (Exception e) {
           res.statusCode = 500;
           return new CodeResponse('Could not parse auth code redirect URI');
       }
      
   }
The response wrapper sets the variables for the code response, including success and error indicators.
// Response Wrapper
   global class CodeResponse {
       String code;
       String sfdc_community_url;
       String sfdc_community_id;
       String state;
       Boolean success;
       String errMsg;
      
       public CodeResponse(String code, String sfdc_community_url, String sfdc_community_id, String state) {
           this.code = code;
           this.sfdc_community_url = sfdc_community_url;
           this.sfdc_community_id = sfdc_community_id;
           this.state = state;
           this.success = true;
       }
      
        public CodeResponse(String errMsg) {
           this.success = false;
           this.errMsg = this.errMsg;
       }       
   }

PHP: Hypertext Preprocessor (PHP) を使用したコード抽出の別の例を次に示します。

<?
header('Access-Control-Allow-Headers: *');
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json; charset=utf-8');
$out = [];
foreach ($_GET as $name => $value) {
   $out[$name] = $value;
}
echo json_encode($out);
?>

コードを抽出したら、コールバックハンドラーがそのコードをブラウザーに送信します。

アプリケーションがコード応答を受信してコード交換を実行する

ブラウザーがコード応答を受信します。ブラウザーのコンソールログ内の成功した応答例を次に示します。

{"success":true,"state":"https://MyExperienceCloudSite.my.site.com/","sfdc_community_url":"https://MyExperienceCloudSite.my.site.com/vforcesite","sfdc_community_id":"0DBxxxxxxxxxxxx","errMsg":null,"code":"aPrxC1*******"}

ブラウザーがヘッドレスでコードをアクセストークンと交換することを要求します。クライアント側の JavaScript の例では、doCodeExchange 関数は POST 要求のコードを Experience Cloud トークンエンドポイントに送信します。

ブラウザーにコンシューマーの秘密が公開されないようにするには、外部クライアントアプリケーションまたは接続アプリケーションの [Web サーバーフローの秘密が必要] および [更新トークンフローの秘密が必要] 設定を無効にする必要があります。これらの設定を無効にした場合、認証要求にコンシューマーの秘密は必要ありません。可能な場合は、サーバーのバックエンドを使用してコード交換を実行することをお勧めします。「ヘッドレス ID API: 非公開クライアントの認証コードとログイン情報フロー」を参照してください。

var clientId = "<Connected App Client ID>";
var baseURL = "<Experience Cloud Domain>";
var redirectURL = "<Experience Cloud Domain>/services/apexrest/code/extraction"
      
// Performs the code exchange
function doCodeExchange(authorizeResponse) {
   //Perform Code Exchange
   //Get Access Token
   var client = new XMLHttpRequest();
   client.open("POST", authorizeResponse.sfdc_community_url + "/services/oauth2/token", true);
   client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   client.send("code=" + authorizeResponse.code + "&grant_type=authorization_code&client_id=" + clientId + "&redirect_uri=" + redirectURL);
   client.onreadystatechange = function() {
       if(this.readyState == 3) {
           response = JSON.parse(client.response);
           getUserInfo(response.access_token, response.sfdc_community_url)
       }
   }
} 

アクセストークン要求では、POST 要求のみを使用できます。GET 要求はサポートされていません。Content-Type ヘッダーを含める必要があります。リクエストボディに次の必須パラメーターを含めます。

パラメーター説明
client_id 外部クライアントアプリケーションまたは接続アプリケーションのコンシューマー鍵。
code 認証サーバーは、認証コード (有効期間が短いトークン) を作成し、認証の成功後にクライアントに渡します。クライアントは、認証コードを認証サーバーに送信してアクセストークンと、必要に応じて更新トークンを取得します。
grant_type 安全な訪問者であることを証明するためにアプリケーションが提供できる検証の種別。認証コードとログイン情報フローの場合、値は authorization_code である必要があります。
redirect_uri

認証に成功した後にユーザーがリダイレクトされる URL。リダイレクト URI は、外部クライアントアプリケーションまたは接続アプリケーションの [コールバック URL] 項目の値のいずれかと一致する必要があります。それ以外の場合、承認は失敗します。

公開クライアントの場合、リダイレクト URI は Salesforce からの 302 リダイレクトを処理できるエンドポイントを参照する必要があります。開発を簡略化するには、https://MyExperienceCloudSite.my.site.com/services/oauth2/echo などの OAuth エコーエンドポイントを使用します。

次の例では、Apex REST コード抽出エンドポイントを使用しています。たとえば、<Experience Cloud Domain>/services/apexrest/code/extraction です。

必要に応じて、トークン要求に次のパラメーターを含めることもできます。

パラメーター説明
client_secret 外部クライアントアプリケーションまたは接続アプリケーションのコンシューマーの秘密。
code_verifier

PKCE 拡張機能を使用している場合は必須です。code 値の推測を困難にするために、高エントロピーの 128 バイトのランダムなデータを指定します。このパラメーターを設定すると、認証コードの傍受攻撃を防ぐのに役立ちます。この値は、https://tools.ietf.org/html/rfc4648#section-5 の定義に従って base64url エンコードする必要があります。

  • トークン要求で code_verifier 値が指定され、認証要求で code_challenge 値が指定されている場合、Salesforce により code_verifier が code_challenge と比較されます。code_verifier が無効であるか一致しない場合、ログインが invalid_grant エラーコードで失敗します。
  • トークンリクエストで code_verifier 値が指定されていても、認証リクエストで code_challenge 値が指定されていない場合、ログインが invalid_grant エラーコードで失敗します。
format

応答の想定される形式。Salesforce では、次の形式をサポートします。

  • urlencoded
  • json (デフォルト)
  • xml

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 ユーザーを識別し、ユーザーの詳細を照会するために使用できる ID URL。「ID URL」を参照してください。
instance_url ユーザーの組織のインスタンスを示す URL。例: https://yourInstance.salesforce.com/。
issued_at 署名が作成されたときのタイムスタンプ (UTC の 1970-01-01T0:0:0Z からのミリ秒数として表記)。
signature Base64 エンコードされた、client_secret で署名された HMAC-SHA256 署名。署名には連結された ID と issued_at value を含めることができます。これらを使用して、ID URL がサーバーから送信された後に変更されていないことを確認できます。
sfdc_community_url Experience Cloud サイトの URL。
sfdc_community_id ユーザーの Experience Cloud サイト ID。
token_type Bearer トークン種別。アクセストークンを含むすべての応答で使用します。

アクセストークン応答には次のパラメーターを含めることもできます。

パラメーター 説明
id_token

ユーザーの一意の識別子、トークンがいつ発行されたかを示すタイムスタンプなど、認証済みユーザーの属性が含まれる署名済みデータ構造。ID トークンによって要求元のクライアントアプリケーションも識別されます。「OpenID Connect の仕様」を参照してください。

このパラメーターは、scope パラメーターに openid が含まれている場合に返されます。

refresh_token Web サーバー、ユーザーエージェント、またはハイブリッドアプリケーショントークンフローから取得したトークン。この値は秘密です。適切な対策を講じて保護してください。このパラメーターは、refresh_token スコープを使用して外部クライアントアプリケーションまたは接続アプリケーションが設定されている場合にのみ返されます。
state クライアントが要求した状態。この値は、state パラメーターが元のクエリ文字列に含まれている場合にのみ含まれます。

アプリケーションがトークン応答を処理してユーザーセッションを作成する

ブラウザーがトークン応答からの情報を保存し、ユーザーセッションを作成します。この時点では、ユーザーはログイン済みで、クライアント側の JavaScript は Salesforce ユーザー情報エンドポイントをコールして、ログインが成功したことを確認します (次の抜粋を参照)。

メモ
メモ アクセストークンストレージの完全なセキュリティレビューを完了していることを確認します。ブラウザーのローカルストレージにアクセストークンを保存しないでください。可能な場合は Cookie に保存しないでください。
// Gets User Info
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 API などの保護されている Salesforce エンドポイントに認証されたコールを実行します。

エンドユーザーが Salesforce データにアクセスできる

ユーザーはアプリケーションで、保護されている Salesforce データにアクセスできるようになりました。たとえば、旅行予約履歴を表示できます。エンドユーザー側では、ログインからデータにアクセスするまでのプロセス全体が、アプリケーションを離れる必要がなく行われました。

 
読み込み中
Salesforce Help | Article