このドキュメントでは、スマートフォン、タブレット、パソコンなどのデバイスにインストールされたアプリケーションが、Google の OAuth 2.0 エンドポイントを使用して Google API へのアクセスを承認する方法について説明します。
OAuth 2.0 を使用すると、ユーザー名やパスワードなどの情報を非公開にしたまま、特定のデータをアプリケーションと共有できます。たとえば、あるアプリケーションでは、OAuth 2.0 を使用して、ユーザーから Google ドライブにファイルを保存する権限を取得できます。
インストール済みのアプリは個別のデバイスに配信されるため、これらのアプリはシークレットを保持できないと想定されます。ユーザーがアプリを使用しているときや、アプリがバックグラウンドで実行されているときに、Google API にアクセスできます。
この承認フローは、ウェブサーバー アプリケーションで使用される承認フローに似ています。主な違いは、インストール済みのアプリがシステム ブラウザを開き、Google の承認サーバーからのレスポンスを処理するためにローカル リダイレクト URI を指定する必要があることです。
代替機能
モバイルアプリの場合は、Android または iOS 向けの Google ログインを使用することをおすすめします。認証とユーザー認証を処理する Google ログイン クライアント ライブラリは、ここで説明する下位レベルのプロトコルよりも実装が簡単な場合があります。
システム ブラウザをサポートしていないデバイスや、テレビ、ゲーム機、カメラ、プリンタなど、入力機能が制限されたデバイス上で実行されるアプリについては、テレビとデバイスでの OAuth 2.0 またはテレビと制限付き入力デバイスでのログインをご覧ください。
ライブラリとサンプル
このドキュメントで説明する OAuth 2.0 フローの実装に役立つ以下のライブラリとサンプルをおすすめします。
Prerequisites
プロジェクトでAPI を有効にする
Google API を呼び出すアプリケーションでは、 API Consoleで API を有効にする必要があります。
プロジェクトで API を有効にするには:
- Google API ConsoleのOpen the API Library 。
- If prompted, select a project, or create a new one.
- API Library には、利用可能なすべての API がプロダクト ファミリーと人気度に応じて分類されて表示されます。有効にしたい API がリストで見当たらない場合は、検索してその API を探すか、属しているプロダクト ファミリーの [すべて表示] をクリックします。
- 有効にする API を選択し、[有効にする] ボタンをクリックします。
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
承認認証情報を作成する
OAuth 2.0 を使用して Google API にアクセスするアプリケーションには、Google の OAuth 2.0 サーバーに対してアプリケーションを識別するための認証情報が必要です。次の手順では、プロジェクトの認証情報を作成する方法について説明します。アプリケーションはその認証情報を使用して、そのプロジェクトで有効にした API にアクセスできます。
- Go to the Credentials page.
- [認証情報を作成] > [OAuth クライアント ID] をクリックします。
- 以下のセクションでは、Google の承認サーバーがサポートしているクライアント タイプとリダイレクト方法について説明します。アプリケーションに合ったクライアント タイプを選択し、OAuth クライアントに名前を付け、必要に応じてフォームの他のフィールドを設定します。
カスタム URI スキーム(Android、iOS、UWP)
カスタム URI スキームは、Android アプリ、iOS アプリ、ユニバーサル Windows プラットフォーム(UWP)アプリで推奨されます。
Android
- アプリケーションの種類として [Android] を選択します。
- OAuth クライアントの名前を入力します。この名前はプロジェクトの Credentials page に表示され、クライアントを識別します。
- Android アプリのパッケージ名を入力します。この値は、アプリ マニフェスト ファイルの
<manifest>
要素のpackage
属性で定義されます。 - アプリの配布の SHA-1 署名証明書のフィンガープリントを入力します。
- アプリで Google Play アプリ署名を使用している場合は、Google Play Console のアプリ署名ページから SHA-1 フィンガープリントをコピーします。
- 独自のキーストアと署名鍵を管理する場合は、Java に含まれている keytool ユーティリティを使用して証明書情報を人が読める形式で出力します。keytool 出力の
Certificate fingerprints
セクションのSHA1
値をコピーします。詳細については、Android 向け Google API ドキュメントのクライアントの認証をご覧ください。
- [作成] をクリックします。
iOS
- アプリケーションの種類として [iOS] を選択します。
- OAuth クライアントの名前を入力します。この名前はプロジェクトの Credentials page に表示され、クライアントを識別します。
- アプリのバンドル ID を入力します。バンドル ID は、アプリの情報プロパティ リストのリソース ファイル(info.plist)にある CFBundleIdentifier キーの値です。この値は、Xcode プロジェクト エディタの [General] ペインまたは [Signing & Capabilities] ペインに最もよく表示されます。バンドル ID は、Apple の App Store Connect サイトにあるアプリの [アプリ情報] ページの [全般情報] セクションにも表示されます。
- (省略可)。
アプリが Apple の App Store で公開されている場合は、そのアプリの App Store ID を入力します。ストア ID は、すべての Apple App Store の URL に含まれる数値文字列です。
- iOS または iPadOS デバイスで Apple App Store アプリを開きます。
- 自分のアプリを探します。
- 共有ボタン(正方形と上矢印)を選択します。
- [リンクをコピー] を選択します。
- コピーしたテキストをテキスト エディタに貼り付けます。App Store ID は URL の最後の部分です。
例:
https://apps.apple.com/app/google/id284815942
- (省略可)。
チーム ID を入力します。詳しくは、Apple デベロッパー アカウントのドキュメントでチーム ID を確認するをご覧ください。
- [作成] をクリックします。
UWP
- アプリケーションの種類として [ユニバーサル Windows プラットフォーム] を選択します。
- OAuth クライアントの名前を入力します。この名前はプロジェクトの Credentials page に表示され、クライアントを識別します。
- アプリの 12 文字の Microsoft ストア ID を入力します。この値は、Microsoft パートナー センターの [アプリの管理] にある [アプリ ID] ページで確認できます。
- [作成] をクリックします。
UWP アプリの場合、カスタム URI スキームは 39 文字以下にする必要があります。
ループバック IP アドレス(macOS、Linux、Windows パソコン)
この URL を使用して認証コードを受信するには、アプリケーションがローカル ウェブサーバーでリッスンしている必要があります。多くのプラットフォームで可能です。ただし、プラットフォームでサポートされていれば、認証コードを取得するための推奨メカニズムです。
アプリが認証レスポンスを受け取ったら、ブラウザを終了してアプリに戻るよう指示する HTML ページを表示することで、ユーザビリティを最大限に高めます。
推奨される使い方 | macOS、Linux、Windows デスクトップ(ユニバーサル Windows プラットフォームを除く) |
フォームの値 | アプリケーションの種類を [デスクトップ アプリ] に設定します。 |
手動でのコピーと貼り付け
アクセス スコープを特定する
スコープを使用すると、アプリケーションは必要なリソースへのアクセス権のみをリクエストできると同時に、ユーザーはアプリケーションに付与するアクセス権の量を制御できます。そのため、リクエストされたスコープの数とユーザーの同意を取得する可能性の間には、反比例する可能性があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセスする必要があるスコープを特定することをおすすめします。
OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの完全なリストが記載されています。
OAuth 2.0 アクセス トークンの取得
次の手順は、ユーザーに代わって API リクエストを実行することをユーザーの同意を得て、アプリケーションが Google の OAuth 2.0 サーバーとやり取りする方法を示しています。アプリケーションで、ユーザー認証が必要な Google API リクエストを実行する前に、ユーザーの同意を得る必要があります。
ステップ 1: コード検証ツールとチャレンジを生成する
Google では、インストール済みのアプリフローのセキュリティを強化するために Proof Key for Code Exchange(PKCE)プロトコルをサポートしています。すべての承認リクエストに対して一意のコード検証ツールが作成され、「code_challenge」という変換された値が認証サーバーに送信され、認証コードが取得されます。
コード 検証ツールを作成する
code_verifier
は、予約されていない文字 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" を使用した高エントロピー暗号ランダム文字列で、最小文字数は 43 文字、最大文字数は 128 文字です。
コード検証ツールには、値を推測するのに現実的でないエントロピーが必要です。
コードチャレンジを作成する
コードチャレンジを作成する 2 つの方法がサポートされています。
コードチャレンジの生成方法 | |
---|---|
S256(推奨) | コードチャレンジは、Base64URL(パディングなし)でエンコードされた、コード検証ツールの SHA256 ハッシュです。
|
プレーン | コードによる確認は、上記で生成したコード検証ツールと同じです。
|
ステップ 2: Google の OAuth 2.0 サーバーにリクエストを送信する
ユーザー認証を取得するには、Google の承認サーバー(https://accounts.google.com/o/oauth2/v2/auth
)にリクエストを送信します。このエンドポイントは、アクティブなセッション検索を処理し、ユーザーを認証してユーザーの同意を得ます。このエンドポイントは SSL でのみアクセス可能で、HTTP(非 SSL)接続を拒否します。
認可サーバーは、インストール済みのアプリケーションについて次のクエリ文字列パラメータをサポートします。
パラメータ | |||||||
---|---|---|---|---|---|---|---|
client_id |
必須 アプリケーションのクライアント ID。この値は、 API Console Credentials pageで確認できます。 |
||||||
redirect_uri |
必須 Google の認可サーバーがアプリに応答する方法を指定します。インストール済みのアプリで使用できるリダイレクト オプションは複数あり、特定のリダイレクト方法を念頭に置いて認証情報を設定します。 この値は、クライアントの API Console
Credentials pageで設定した OAuth 2.0 クライアントの承認済みのリダイレクト URI のいずれかと完全に一致する必要があります。この値が承認済み URI と一致しない場合は、 次の表に、それぞれのメソッドに適した
|
||||||
response_type |
必須 Google OAuth 2.0 エンドポイントが認証コードを返すかどうかを指定します。 インストール済みのアプリのパラメータ値を |
||||||
scope |
必須 アプリケーションがユーザーに代わってアクセスできるリソースを識別するためのスコープのスペース区切りリスト。これらの値により、Google がユーザーに表示する同意画面が表示されます。 スコープを使用すると、アプリケーションは必要なリソースへのアクセス権のみをリクエストできます。また、ユーザーはアプリケーションに付与するアクセス権の量を制御できます。したがって、要求されるスコープの数とユーザーの同意を取得する可能性の間には、逆の関係があります。 |
||||||
code_challenge |
推奨
認証コードの交換中にサーバー側のチャレンジとして使用される、エンコードされた |
||||||
code_challenge_method |
推奨
認証コードの交換中に使用される |
||||||
state |
推奨
アプリケーションが承認リクエストと承認サーバーのレスポンスの間で状態を維持するために使用する文字列値を指定します。ユーザーがアプリのアクセス リクエストを同意または拒否した後、 このパラメータは、アプリ内の適切なリソースにユーザーを誘導する、ノンスを送信する、クロスサイト リクエスト フォージェリを軽減するなどの目的で使用できます。 |
||||||
login_hint |
省略可 アプリケーションが認証しようとしているユーザーを認識している場合、このパラメータを使用して Google 認証サーバーにヒントを提供できます。サーバーはこのヒントを使用して、ログイン フォームにメールのフィールドに入力するか、適切なマルチログイン セッションを選択することで、ログインフローを簡素化します。 パラメータ値をメールアドレスまたは |
認証 URL の例
以下のタブには、各リダイレクト URI オプション用の承認 URL の例が記載されています。
これらの URL は、redirect_uri
パラメータの値を除き同じです。この URL には、必須の response_type
パラメータと client_id
パラメータ、省略可能な state
パラメータも含まれています。各 URL には、読みやすくするために改行とスペースが含まれています。
カスタム URI スキーム
https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=com.example.app%3A/oauth2redirect& client_id=client_id
ループバック IP アドレス
https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=http%3A//127.0.0.1%3A9004& client_id=client_id
ステップ 3: Google が同意を求める
このステップでは、リクエストされたアクセス権をアプリケーションに付与するかどうかを決定します。この段階で、Google はアプリケーションの名前と、ユーザーの認証情報を使用してアクセスをリクエストする Google API サービス、および付与されるアクセス スコープを示す同意ウィンドウを表示します。ユーザーは、アプリケーションからリクエストされた 1 つ以上のスコープへのアクセス権を付与する、またはリクエストを拒否することに同意できます。
Google の OAuth 2.0 サーバーからのレスポンス(アクセスが許可されたかどうか)からのレスポンスを待機するため、この段階ではまだ何もする必要はありません。このレスポンスについては、次のステップで説明します。
エラー
Google の OAuth 2.0 認証エンドポイントへのリクエストでは、予想される認証および認可フローの代わりにユーザー向けのエラー メッセージが表示されることがあります。一般的なエラーコードと推奨される解決策を以下に示します。
admin_policy_enforced
Google Workspace 管理者のポリシーにより、リクエストされた 1 つ以上のスコープを Google アカウントが承認できません。OAuth クライアント ID にアクセス権が明示的に付与されるまで、すべてのスコープまたは機密性の高いスコープへのアクセスが制限される仕組みについて詳しくは、Google Workspace 管理者のヘルプ記事 「Google Workspace のデータにアクセスできるサードパーティ製アプリと内部アプリを制御する」をご覧ください。
disallowed_useragent
認証エンドポイントは、Google の OAuth 2.0 ポリシーで許可されていない埋め込みユーザー エージェント内に表示されています。
Android
Android デベロッパーは、android.webkit.WebView
で承認リクエストを開くと、このエラー メッセージを受け取ることがあります。代わりに、Android 向け Google ログインや OpenID Foundation の AppAuth for Android などの Android ライブラリを使用する必要があります。
このエラーは、Android アプリが埋め込みのユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認証エンドポイントに移動したときに発生することがあります。デベロッパーは、Android App Links ハンドラまたはデフォルトのブラウザアプリの両方を含む、オペレーティング システムのデフォルトのリンク ハンドラで一般的なリンクを開くことができるようにする必要があります。Android カスタムタブ ライブラリもサポートされています。
iOS
iOS と macOS のデベロッパーは、WKWebView
で承認リクエストを開いたときにこのエラーが発生することがあります。代わりに、iOS 向け Google ログインや OpenID Foundation の iOS 向け AppAuth などの iOS ライブラリを使用する必要があります。
このエラーは、iOS アプリまたは macOS アプリが埋め込みユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認証エンドポイントに移動したときに発生することがあります。デベロッパーは、Universal Links ハンドラまたはデフォルトのブラウザアプリの両方を含む、オペレーティング システムのデフォルトのリンクハンドラで一般的なリンクを開く必要があります。SFSafariViewController
ライブラリもサポートされているオプションです。
org_internal
リクエスト内の OAuth クライアント ID は、特定の Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。この構成オプションの詳細については、OAuth 同意画面の設定に関するヘルプ記事のユーザータイプをご覧ください。
invalid_grant
コード確認機能と本人確認を使用している場合、code_callenge
パラメータが無効であるか、指定されていません。code_challenge
パラメータが正しく設定されていることを確認します。
アクセス トークンを更新する場合、トークンが期限切れになっているか、無効化されている可能性があります。ユーザーを再度認証し、新しいトークンの取得についてユーザーの同意を得ます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていることと、リクエストで正しいトークンとパラメータを使用していることを確認してください。それ以外の場合は、ユーザー アカウントが削除または無効化されている可能性があります。
redirect_uri_mismatch
承認リクエストで渡された redirect_uri
が、OAuth クライアント ID の承認済みのリダイレクト URI と一致しません。 Google API Console Credentials pageで承認済みのリダイレクト URI を確認してください。
渡された redirect_uri
がクライアント タイプに対して無効である可能性があります。
redirect_uri
パラメータは、サポートが終了し、サポートされなくなった OAuth 帯域外(OOB)フローを参照する場合があります。統合を更新するには、移行ガイドをご覧ください。
ステップ 4: OAuth 2.0 サーバー レスポンスを処理する
アプリケーションが承認レスポンスを受信する方法は、使用するリダイレクト URI スキームによって異なります。スキームに関係なく、レスポンスには認証コード(code
)またはエラー(error
)が含まれます。たとえば、error=access_denied
はユーザーがリクエストを拒否したことを示します。
ユーザーがアプリケーションへのアクセス権を付与した場合は、次のステップで説明するように、認証コードをアクセス トークンおよび更新トークンと交換できます。
ステップ 5: 認証コードを更新トークンとアクセス トークンに交換する
認証コードをアクセス トークンと交換するには、https://oauth2.googleapis.com/token
エンドポイントを呼び出して、次のパラメータを設定します。
フィールド | |
---|---|
client_id |
Credentials pageから取得したクライアント ID。 API Console |
client_secret |
API Console Credentials pageから取得したクライアント シークレット。 |
code |
最初のリクエストから返された認証コード。 |
code_verifier |
ステップ 1 で作成したコード検証ツール。 |
grant_type |
OAuth 2.0 仕様で定義されているように、このフィールドの値は authorization_code に設定する必要があります。 |
redirect_uri |
特定の client_id の API Console
Credentials page で、プロジェクトに対して指定されているリダイレクト URI の 1 つ。 |
次のスニペットは、リクエストの例を示しています。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=http://127.0.0.1:9004& grant_type=authorization_code
Google はこのリクエストに対して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。
レスポンスには、次のフィールドが含まれます。
フィールド | |
---|---|
access_token |
Google API リクエストの承認用にアプリケーションが送信するトークン。 |
expires_in |
アクセス トークンの残りの存続期間(秒単位)。 |
id_token |
注: このプロパティは、リクエストに ID スコープ(openid 、profile 、email など)が含まれている場合にのみ返されます。値は、ユーザーについてデジタル署名された ID 情報を含む JSON Web Token(JWT)です。 |
refresh_token |
新しいアクセス トークンの取得に使用できるトークン。更新トークンは、ユーザーがアクセス権を取り消すまで有効です。 なお、インストール済みのアプリでは、更新トークンが常に返されます。 |
scope |
access_token によって付与されるアクセスのスコープ。スペース区切りで、大文字と小文字が区別される文字列のリストとして表されます。 |
token_type |
返されるトークンのタイプ。現時点では、このフィールドの値は常に Bearer に設定されます。 |
次のスニペットは、レスポンスの例を示しています。
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Google API の呼び出し
アプリケーションがアクセス トークンを取得した後、その API で必要なアクセス スコープが付与されている場合、特定のユーザー アカウントに代わって、このトークンを使用して Google API を呼び出すことができます。これを行うには、access_token
クエリ パラメータまたは Authorization
HTTP ヘッダー Bearer
値を指定して、API のリクエストにアクセス トークンを含めます。可能であれば、クエリ文字列はサーバーログに表示されるため、HTTP ヘッダーを使用することをおすすめします。ほとんどの場合、クライアント ライブラリを使用して Google API の呼び出しを設定できます(Drive Files API を呼び出すときなど)。
すべての Google API を試し、そのスコープは OAuth 2.0 Playground で確認できます。
HTTP GET の例
Authorization: Bearer
HTTP ヘッダーを使用した
drive.files
エンドポイント(Drive Files API)の呼び出しは次のようになります。独自のアクセス トークンを指定する必要があります。
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
次に示すのは、access_token
クエリ文字列パラメータを使用した認証済みユーザーの同じ API の呼び出しです。
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl
の例
これらのコマンドは、curl
コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプション(推奨)を使用する例を次に示します。
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
または、クエリ文字列パラメータ オプションを使用します。
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
アクセス トークンをリフレッシュする
アクセス トークンは定期的に期限が切れ、関連する API リクエストに対して無効な認証情報になります。トークンに関連付けられたスコープへのオフライン アクセスをリクエストした場合、アクセス トークンの更新をユーザーに求めることなく(ユーザーが不在の場合も含め)、更新できます。
アクセス トークンを更新するために、アプリケーションは、次のパラメータを含む HTTPS POST
リクエストを Google の承認サーバー(https://oauth2.googleapis.com/token
)に送信します。
フィールド | |
---|---|
client_id |
API Consoleから取得したクライアント ID。 |
client_secret |
API Consoleから取得したクライアント シークレット。
(Android、iOS、Chrome のアプリケーションとして登録されたクライアントからのリクエストには client_secret は適用されません)。 |
grant_type |
OAuth 2.0 仕様で定義されているように、このフィールドの値は refresh_token に設定する必要があります。 |
refresh_token |
認証コード エクスチェンジから返される更新トークン。 |
次のスニペットは、リクエストの例を示しています。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
ユーザーは、アプリケーションに対して付与されたアクセス権を取り消さない限り、新しいアクセス トークンを含む JSON オブジェクトを返します。次のスニペットは、レスポンスの例を示しています。
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
発行される更新トークンの数には上限があります(クライアントとユーザーの組み合わせごとに 1 つずつ、すべてのクライアントで 1 つの上限があります)。更新トークンは長期保存し、有効な限り、継続的に使用する必要があります。アプリケーションがリクエストした更新トークンが多すぎると、これらの制限に達する可能性があります。その場合、古い更新トークンは機能しなくなります。
トークンの取り消し
場合によっては、ユーザーはアプリケーションに付与されたアクセス権を取り消すこともできます。ユーザーは、 アカウント設定にアクセスしてアクセス権を取り消すことができます。詳しくは、アカウントにアクセスできるサードパーティのサイトやアプリのアクセス権を削除するをご覧ください。
アプリケーションに、付与されたアクセス権をプログラマティックに取り消すこともできます。 プログラムによる取り消しは、ユーザーが登録解除したり、アプリを削除したり、アプリで必要な API リソースが大幅に変更された場合に重要です。言い換えると、削除プロセスの一部では、これまでアプリに付与された権限が確実に削除されるよう API リクエストを追加することが可能です。
プログラムでトークンを取り消すには、アプリケーションが https://oauth2.googleapis.com/revoke
にリクエストを行い、パラメータとしてトークンを含めます。
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
トークンには、アクセス トークンまたは更新トークンを指定できます。トークンがアクセス トークンであり、対応する更新トークンがある場合、更新トークンも取り消されます。
取り消しが正常に処理されると、レスポンスの HTTP ステータス コードは 200
になります。エラー状態の場合、エラーコードとともに HTTP ステータス コード 400
が返されます。
関連情報
IETF の現在のベスト プラクティスのネイティブ アプリ向け OAuth 2.0 には、ここに記載されているベスト プラクティスの多くが確立されています。