「開発:OAuth 2 API」の版間の差分

提供:MoodleDocs
移動先:案内検索
編集の要約なし
(done.)
 
(同じ利用者による、間の60版が非表示)
2行目: 2行目:
{{ Moodle 3.3 }}
{{ Moodle 3.3 }}


作成中です - [[利用者:Mitsuhiro Yoshida|Mitsuhiro Yoshida]] ([[利用者・トーク:Mitsuhiro Yoshida|トーク]])
OAuth 2 APIはリモートシステムとの統合のためのOAuth 2機能を提供するクラス群です。これらは「/lib/classes/oauth2/」フォルダに存在します。OAuth 2 APIには注意すべきいくつかのコンセプトがあります。
 
OAuth 2 APIはリモートシステムとの統合のためのOAuth 2機能を提供するクラス群です。これらは「/lib/classes/oauth2/」フォルダに存在します。また注意すべきいくつかのコンセプトがあります。


=== イシュア ===
=== イシュア ===
OAuthイシュアとはOAuthアクセストークンを発行してIDおよびAPIアクセスを提供する名前付きの外部システムです。これらは「サイト管理 -> サーバ -> OAuth 2サービス」で手動設定できます。一般的なOAuthアクセストークンはテンプレート (Google、Office 365、Facebook) からすぐに作成できます。イシュアは名前およびアイコン(ログインページに表示)、クライアントIDおよびクライアントシークレット (OAuth仕様の一部) を持ちます。
OAuthイシュアとはOAuthアクセストークンを発行してIDおよびAPIアクセスを提供する名前付きの外部システムです。これは「サイト管理 -> サーバ -> OAuth 2サービス」で手動設定できます。一般的なOAuthアクセストークンはテンプレート (Google、Office 365、Facebook) からすぐに作成できます。イシュアは名前およびアイコン(ログインページに表示)、クライアントIDおよびクライアントシークレット (OAuth仕様の一部) を持ちます。


=== エンドポイント  ===
=== エンドポイント  ===
OAuth発行者はアクセストークンの取得および交換、ID情報の取得に使用するURLであるいくつかのエンドポイントを定義しておく必要があります。テンプレートから作成したOAuthサービスおよびOpen ID Connectを使ったOAuthサービスではこれらは自動的に設定されます。
OAuthイシュアはアクセストークンの取得および交換、ID情報の取得に使用するURLであるいくつかのエンドポイントを定義しておく必要があります。テンプレートから作成したOAuthサービスおよびOpen ID Connectを使ったOAuthサービスではこれらは自動的に設定されます。


The 3 standard endpoints which must be defined are the "authorization endpoint", "token endpoint" and "userinfo endpoint" - these are 3 urls which are used by the OAuth protocol to "allow the user to login", "obtain tokens to access the api" and "get the logged in user information".
定義すべき標準的なエンドポイントは「認証エンドポイント」「トークンエンドポイント」「ユーザ情報エンドポイント」の3つです。これはOAuthプロトコルによって「ユーザのログインを許可」「APIにアクセスするためのトークンを取得」「ログインしたユーザ情報を取得」するための3つのURLとなります。


=== Open ID Connect ===
=== Open ID Connect ===
Open ID Connect is a protocol built on top of OAuth 2 which provides some standardisation and inter-operability for OAuth 2 based services. If a "base service url" is entered for an Issuer - Moodle will attempt to retrieve the "well known configuration" which provides all the information about the other endpoints required to complete the setup for this service. E.g. for Google - the base service url is "https://accounts.google.com/". By appending ".well-known/openid-configuration" to the url we can find the service description at https://accounts.google.com/.well-known/openid-configuration which contains all the required information for us to automatically complete the setup for this service. This will work with any Open ID connect compliant service.
Open ID ConnectはOAuth 2の上に構築されたプロトコルであり、OAuth 2ベースのサービスに標準化および相互運用性を提供します。もし「基本サービスURL」がイシュアに入力された場合、Moodleはこのサービスの設定を完了するために必要な他のエンドポイントに関するすべての情報を提供する「よく知られた設定」を取得するよう試みます。例) Googleの場合 - 基本サービスのURLは「https://accounts.google.com/」です。このURLに「.well-known/openid-configuration」 を付加してhttps://accounts.google.com/.well-known/openid-configurationにあるサービス説明文を閲覧できます。説明文にはこのサービスの設定を自動的に完了させるために必要な情報すべてを含みます。これはOpen ID connectに準拠したサービスであればどれでも動作します。


=== Open Badge Connect API ===
=== Open Badge Connect API ===
Open Badge Connect API is a specification built by IMS Global which provides some standardisation and interoperability for OAuth 2 based services. If a "base service URL" is entered for an Issuer, Moodle will attempt to retrieve the "well-known configuration" (.well-known/badgeconnect.json) which provides all the information about the endpoints required to complete the setup for this service. Besides, if no client id and secret are given, the registration endpoint will be called to get them (and safe time and effort to the admin).
Open Badge Connect APIはIMS Global社により策定されたOAuth 2ベースサービスの標準化および相互運用性を提供するための仕様です。イシュアに「基本サービスURL」が入力された場合、Moodleはこのサービスの設定を完了するために必要なエンドポイントに関するすべての情報を提供する「よく知られた設定」(well-known/badgeconnect.json) を取得するよう試みます。さらにクライアントIDおよびシークレットが与えられていない場合、それらを取得するために登録エンドポイントがコールされます (そして管理者に安全な時間および労力を提供します)
E.g. for IMS Global testing platform, the base service URL is "https://dc.imsglobal.org/". By appending ".well-known/badgeconnect.json" to the URL we can find the service description which contains all the required information for us to automatically complete the setup for this service (endpoints, client id and secret, image...).
例) IMS Globalテストプラットフォームの場合、基本サービスのURLは「https://dc.imsglobal.org/」です。私たちはこのURLに「.well-known/badgeconnect.json」を追加してこのサービスのセットアップを自動的に完了するために必要なすべての情報 (エンドポイント、クライアントIDと秘密、画像 ...) を含むサービスの説明を確認できます。


=== User field mappings ===
=== ユーザフィールドマッピング ===
The other information we need to know about an OAuth 2 service is how to map the user information into Moodle user fields. We do this by adding to the list of user field mappings for the Issuer. The mappings for Open ID Connect services are standard and will be automatically created when setting up an Open ID compliant service - for other services you will need to create the mappings manually. Moodle will use this information to import the user profile fields when creating new accounts. The most important user field mappings are the username and email which are used to identify the Moodle account associated with the OAuth 2 login.
OAuth 2サービスに関して私たちが知るべき他の情報はユーザ情報をMoodleのユーザフィールドにマッピングする方法です。イシュア用のユーザフィールドマッピングのリストにユーザ情報を追加することによりマッピングします。Open ID Connectサービス用のマッピングは標準的なものでOpen IDに準拠したサービスをセットアップする際に自動作成されます。新しいアカウントを作成する場合、Moodleはユーザプロファイルのフィールドをインポートするためにこの情報を使用します。最も重要なユーザフィールドのマッピングはOAuth 2ログインに関連するMoodleアカウントを識別するために使用されるユーザ名およびメールアドレスです。




== How a new issuer service should be implemented? ==
== 新しいイシュアサービスをどのように実装するのか? ==
Any OAuth2 Service should have a class into the lib/classes/oauth2/service/ folder extending from a discovery system (core\oauth2\discovery\base_definition) and implementing core\oauth2\service\issuer_interface:
いかなるOAuth2サービスにおいてもlib/classes/oauth2/service/フォルダにディスカバリシステムから拡張されたクラス (core\oauth2\discovery\base_definition) およびcore\oauth2\service\issuer_interfaceの実装が必要です:


* Discovery system indicates the way the endpoints should be obtained.
* ディスカバリシステムではエンドポイントを取得する方法を示します。
* Issuer interface has several common methods, called from lib/classes/oauth2/api.php to initialise or discover endpoints.
* イシュアインタフェースにはいくつかの共通メソッドがあり、エンドポイントを初期化または発見するためlib/classes/oauth2/api.phpからコールされます。


<syntaxhighlight lang="php">class google extends openidconnect implements issuer_interface {
<syntaxhighlight lang="php">class google extends openidconnect implements issuer_interface {
40行目: 38行目:




== I set up an OAuth 2 Issuer - how do I use it in code? ==
== OAuth 2イシュアを設定しました - コード内でどのように使えばよいですか? ==
Any plugin that wants to use the configuration information provided by an OAuth issuer first needs to determine which issuer they should use for authentication. This is typically done by adding a setting that lets the admin choose from the list of configured issuers. An example is the "Google Drive" repository. It's possible to have multiple, very similar OAuth Issuers configured e.g. One public Google Issuer and one that is restricted to a specific domain. Once we know the Issuer we wish to use we can use it's ID to get an \core\oauth2\client class which will let us make requests against that API.
まずどのイシュアを利用して認証するかをOAuthイシュアが提供する設定情報を利用したいプラグインでは決定する必要があります。これは通常、管理者が設定されたイシュアのリストから選択できるようにする設定追加で実現できます。例えば「Google Drive」リポジトリのようなものです。似たようなOAuthイシュアの複数設定も可能です。例えば公開されているGoogleのイシュアおよび特定のドメインに限定されたイシュアがあります。使用したいイシュアが分かった場合、私たちはそのIDを使用してAPIに対してリクエストできるイシュアクラス (IssuerClient) を取得できます。


<syntaxhighlight lang="php">// Get an issuer from the id.
<syntaxhighlight lang="php">// IDからイシュアを取得します。
$issuer = \core\oauth2\api::get_issuer($issuerid);
$issuer = \core\oauth2\api::get_issuer($issuerid);
// Get an OAuth client from the issuer.
// イシュアからOAuthクライアントを取得します。
$client = \core\oauth2\api::get_user_oauth_client($this->issuer, $returnurl, $scopes);                          
$client = \core\oauth2\api::get_user_oauth_client($this->issuer, $returnurl, $scopes);


</syntaxhighlight>
</syntaxhighlight>


Despite what is said in the code documentation, it is best to check that the client is authenticated and if not,  redirect the user to log in.
コードドキュメントに書かれている内容に拘わらず、クライアントが認証されているかどうかを確認して、認証されていない場合はログインするようユーザをリダイレクトするのがベストです。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
58行目: 56行目:
</syntaxhighlight>  
</syntaxhighlight>  


'''What is return URL?'''  
'''戻りURLとは何ですか?'''  
 
これはあなたを現在のページから元のページに戻すためのURLです。OAuthの仕組みはOAuthクライアントを取得するための呼び出しで私たちに必要なスコープすべてを持つ有効なセッションがあるかどうか確認するというものです。私たちにセッションがない場合、直ちにOAuthログインページにリダイレクトされます。ログインできた場合、Moodleの「returnurl」にリダイレクトされてOAuthクライアントを取得するために同じ呼び出しが実行されます - 今回は有効なセッションがあるため、クライアントが返されます。returnurlにはパラメータの1つとしてsesskeyを含む必要があります。


This is a url that will take you back to the current page. The way OAuth works is that the call to get the OAuth client will check to see if we have a valid session with all of the required scopes. If we don't - the user will be redirected immediately to the OAuth login page. When they have logged in - they are redirected back to the "returnurl" in Moodle which must end up making the same call to get an OAuth client - except this time we have a valid session so the client is returned. The returnurl MUST include the sesskey as one of the parameters.
'''スコープとは何ですか?'''


'''What are the scopes?'''
これは「パーミッショングラント」(パーミッション許可) と名付けられユーザは承諾を求められます。 例えば「email」はあなたがログインしているアカウントのメールアドレスをMoodleが確認できるようにするスコープです。要求された各パーミッションはその意味の説明とともにユーザに表示されるため、ユーザはMoodleにこのレベルのアクセスを「許可」にする必要があります - 許可しない場合は操作をキャンセルしてください。一度に必要以上のスコープを要求せずにMoodleの異なる機能で使用されそうなスコープを段階的に追加要求することが最良の方法です。例えばMoodleにログインする場合、私たちはユーザの基本プロファイルおよびメールアドレスへのアクセスを要求する必要があるだけです。リポジトリにアクセスする場合 - 私たちはユーザのファイルへの読み込み/書き込みアクセス権を要求する必要があります。私たちはOAuthクライアントクラスを作成する度にOAuthクライアントインスタンスで使用するスコープをリストアップします。もしユーザが要求したスコープの一部しか承認しない場合、追加アクセスレベルを承認するための同意画面にリダイレクトされます。


These are named "permission grants" which the user is asked to accept. E.g. "email" is a scope which allows Moodle to see the email address for your logged in account. Each of the requested permissions will be displayed to the user with a description of what they mean and the user will have to "grant" Moodle this level of access - or cancel the operation. It is best practice not to request more scopes than are needed at any one time, and to incrementally request additional scopes as they are going to be used by different features in Moodle. For example - when logging into Moodle we only need to request access to the users basic profile and email address. When accessing a repository - we will need to request read/write access to the users files. Each time we create an oauth client class, we list the scopes that we will be using with this instance of the oauth client - if the user has only approved some of the scopes we request - they will be redirected to a consent screen where they approve the additional level of access.
それで、OAuthクライアントで何ができますか?


So - what can I do with my oauth client ?
リクエストを作成しましょう! このクラスはmoodle curlクラスを継承していますが、各リクエストには自動的に認証情報を含めます。これは$client->get()または$client->post()のような標準関数を使用して手動で残りのAPI関数を呼び出せることを意味します。またこのクラスはIPアドレスブラックリストおよびプロキシ設定のような設定済みMoodleセキュリティ設定を尊重します。


Make requests! This class extends the moodle curl class but includes authentication information with each request automatically. This means you can use standard functions like $client->get() or $client->post() to manually call rest api functions. This class will also honour the configured Moodle security settings like ipaddress black lists and proxy settings.
API関数を簡単に呼び出すには?


How do I make it easier to call API functions?
外部のrest apiを使いやすくラップするためのヘルパ関数が含まれた抽象クラス\coreauth2restが存在します。使用するには自分のプラグインでサブクラスを作成した上で「get_api_functions()」メソッドを定義してください。


There is an abstract class \core\oauth2\rest which contains helper functions to allow you to wrap a external rest api in an easier to use class. To use it, make a subclass in your own plugin and define the "get_api_functions()" method.


<syntaxhighlight lang="php">/**                                                                                                                               
  * Google Drive Rest API.
  * Google Drive Rest API.                                                                                                          
  *
  *                                                                                                                                
  * @package    fileconverter_googledrive
  * @package    fileconverter_googledrive                                                                                          
  * @copyright  2017 Damyon Wiese
  * @copyright  2017 Damyon Wiese                                                                                                  
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later                                                            
  */
  */                                                                                                                                
namespace fileconverter_googledrive;
namespace fileconverter_googledrive;                                                                                              
 
                                                                                                                                   
defined('MOODLE_INTERNAL') || die();
defined('MOODLE_INTERNAL') || die();                                                                                              
 
                                                                                                                                   
/**
/**                                                                                                                                
  * Google Drive Rest API.
  * Google Drive Rest API.                                                                                                          
  *  
  *                                                                                                                                
  * @copyright  2017 Damyon Wiese
  * @copyright  2017 Damyon Wiese                                                                                                  
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later                                                            
  */
  */                                                                                                                                
class rest extends \core\oauth2\rest {    
class rest extends \core\oauth2\rest {                                                                                            
 
                                                                                                                                   
     /**
     /**                                                                                                                            
     * Define the functions of the rest API.
     * Define the functions of the rest API.                                                                                      
     *
     *                                                                                                                            
     * @return array Example:
     * @return array Example:                                                                                                      
     *  [ 'listFiles' => [ 'method' => 'get', 'endpoint' => 'http://...', 'args' => [ 'folder' => PARAM_STRING ] ] ]
     *  [ 'listFiles' => [ 'method' => 'get', 'endpoint' => 'http://...', 'args' => [ 'folder' => PARAM_STRING ] ] ]              
     */
     */                                                                                                                            
     public function get_api_functions() {  
     public function get_api_functions() {                                                                                          
         return [
         return [                                                                                                                  
             'create' => [
             'create' => [                                                                                                          
                 'endpoint' => 'https://www.googleapis.com/drive/v3/files',
                 'endpoint' => 'https://www.googleapis.com/drive/v3/files',                                                        
                 'method' => 'post',
                 'method' => 'post',                                                                                                
                 'args' => [
                 'args' => [                                                                                                        
                     'fields' => PARAM_RAW  
                     'fields' => PARAM_RAW                                                                                          
                 ],
                 ],                                                                                                                
                 'response' => 'json'
                 'response' => 'json'                                                                                              
             ],
             ],                                                                                                                    
             'delete' => [
             'delete' => [                                                                                                          
                 'endpoint' => 'https://www.googleapis.com/drive/v3/files/{fileid}',
                 'endpoint' => 'https://www.googleapis.com/drive/v3/files/{fileid}',                                                
                 'method' => 'delete',
                 'method' => 'delete',                                                                                              
                 'args' => [
                 'args' => [                                                                                                        
                     'fileid' => PARAM_RAW
                     'fileid' => PARAM_RAW                                                                                          
                 ],      
                 ],                                                                                                                
                 'response' => 'json'
                 'response' => 'json'                                                                                              
             ],
             ],                                                                                                                    
         ];
         ];                                                                                                                        
     }
     }                                                                                                                              
}
}              


</syntaxhighlight>
</syntaxhighlight>


This example defines 2 functions in the external API 'create' and 'delete'. It specifies the http methods to use when calling these functions as well as the list of parameters. It also specifies that these functions return 'json' which means that the rest class will automatically decode the json response into an object. The url for each function call can contain parameters in the url (marked with curly braces). These will be replaced when they are passed as arguments to the function. Any remaining arguments will be appended as query parameters.
この例では外部APIに「create」および「delete」の2つの関数を定義しています。これらの関数を呼び出し時には使用するhttpメソッドおよびパラメータのリストを指定します。また、これらの関数が「json」を返すことも指定しています。 これはRESTクラスがjsonレスポンスを自動的にデコードしてオブジェクトに変換することを意味します。各関数の呼び出しURLにはパラメータを含めることができます (中括弧でマークされています)。これらは関数に引数として渡される際に置き換えられます。残りの引数はクエリパラメータとして追加されます。
 
このクラスを使うには - 私たちはコンストラクタにoauth2クライアントを渡した後、「call」メソッドを使ってAPIから関数を呼び出します。


To use this class - we pass the oauth2 client to the constructor and then use the "call" method to call functions from the api.


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$service = new \fileconverter_googledrive\rest($client);          
$service = new \fileconverter_googledrive\rest($client);


$params = ['fileid' => $fileid];                                                                                                                        
$params = ['fileid' => $fileid];


$service->call('delete', $params);                        
$service->call('delete', $params);
</syntaxhighlight>
</syntaxhighlight>


== How do I call API functions when the user is not logged in (e.g. from a scheduled task)? ==
== ユーザがログインしていない場合、 (スケジュールタスク等から) API関数を呼び出すにはどのようにすればよいですか? ==


Moodle allows you to connect a "system account" to any of the OAuth issuers. This is optional - so before enabling functionality that relies on this level of access you should check that the system account has been connected:
MoodleではあなたがOAuthイシュアのいずれかに「システムアカウント」を接続できます。これは任意です - したがって、このレベルのアクセスに依存する機能を有効にする前にシステムアカウントが接続されていることを確認してください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
145行目: 144行目:
</syntaxhighlight>
</syntaxhighlight>


If a system account has been connected - we can use it to get an authenticated oauth client (no redirects involved).
システムアカウントが接続されている場合、それを使って認証されたoauthクライアントを取得できます (リダイレクトは関係ありません)


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
151行目: 150行目:
</syntaxhighlight>
</syntaxhighlight>


This client can now be used to access apis as the Moodle system user.
このクライアントはMoodleシステムユーザとしてAPIにアクセスできるようになります。


If your code is going to use additional login scopes with this API - it must list all of the scopes it will use in a callback function so that the Moodle administrator can consent and agree to all the scopes when they connect the system account.
あなたのコードがこのAPIで追加ログインスコープを使用する場合、Moodle管理者がシステムアカウントに接続時にすべてのスコープに同意および承諾できるようにコールバック関数で使用するすべてのスコープをリストする必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
**                                                                                                                                
**
  * Callback to get the required scopes for system account.                                                                         
  * システムアカウントに必要なスコープを取得するためのコールバックです。
  *                                                                                                                                
  *
  * @param \core\oauth2\issuer $issuer                                                                                              
  * @param \core\oauth2\issuer $issuer
  * @return string                                                                                                                  
  * @return string
  */                                                                                                                                
  */
function fileconverter_googledrive_oauth2_system_scopes(\core\oauth2\issuer $issuer) {                                            
function fileconverter_googledrive_oauth2_system_scopes(\core\oauth2\issuer $issuer) {
     if ($issuer->get('id') == get_config('fileconverter_googledrive', 'issuerid')) {                                              
     if ($issuer->get('id') == get_config('fileconverter_googledrive', 'issuerid')) {
         return 'https://www.googleapis.com/auth/drive';                                                                            
         return 'https://www.googleapis.com/auth/drive';
     }                                                                                                                              
     }
     return '';                                                                                                                    
     return '';
}   
}   
</syntaxhighlight>
</syntaxhighlight>


The way the system account works is that a Moodle admin "connects" the system account by logging in with this account and accepting the permissions from the "Site administration -> Server -> OAuth 2 Services" page. One of the permissions they must accept is for offline access. This means that Moodle will receive a refresh token and can store it against that issuer. When we need to get a logged in OAuth client - we can exchange the refresh token for an access token directly, without having to login. The refresh token is updated by a scheduled task to make sure it never expires.
システムアカウントの仕組みはMoodle管理者がこのアカウントでログインした後、「サイト管理 -> サーバ -> OAuth 2サービス」ページから権限を受け入れてシステムアカウントに「接続」することです。システムアカウントで受け入れなければならない許可の1つはオフラインアクセスです。これはMoodleが受け取ったリフレッシュトークンをイシュアに対して保存できることを意味します。私たちがログインしているOAuthクライアントを取得する必要がある場合、ログインすることなくリフレッシュトークンとアクセストークンを直接交換できます。リフレッシュトークンはスケジュールタスクによって更新されます。また、リフレッシュトークンが期限切れとなることはありません。


[[en:Development:OAuth_2_API]]
[[en:Development:OAuth_2_API]]

2023年3月22日 (水) 15:04時点における最新版

OAuth 2 API

Moodle 3.3


OAuth 2 APIはリモートシステムとの統合のためのOAuth 2機能を提供するクラス群です。これらは「/lib/classes/oauth2/」フォルダに存在します。OAuth 2 APIには注意すべきいくつかのコンセプトがあります。

イシュア

OAuthイシュアとはOAuthアクセストークンを発行してIDおよびAPIアクセスを提供する名前付きの外部システムです。これは「サイト管理 -> サーバ -> OAuth 2サービス」で手動設定できます。一般的なOAuthアクセストークンはテンプレート (Google、Office 365、Facebook) からすぐに作成できます。イシュアは名前およびアイコン(ログインページに表示)、クライアントIDおよびクライアントシークレット (OAuth仕様の一部) を持ちます。

エンドポイント

OAuthイシュアはアクセストークンの取得および交換、ID情報の取得に使用するURLであるいくつかのエンドポイントを定義しておく必要があります。テンプレートから作成したOAuthサービスおよびOpen ID Connectを使ったOAuthサービスではこれらは自動的に設定されます。

定義すべき標準的なエンドポイントは「認証エンドポイント」「トークンエンドポイント」「ユーザ情報エンドポイント」の3つです。これはOAuthプロトコルによって「ユーザのログインを許可」「APIにアクセスするためのトークンを取得」「ログインしたユーザ情報を取得」するための3つのURLとなります。

Open ID Connect

Open ID ConnectはOAuth 2の上に構築されたプロトコルであり、OAuth 2ベースのサービスに標準化および相互運用性を提供します。もし「基本サービスURL」がイシュアに入力された場合、Moodleはこのサービスの設定を完了するために必要な他のエンドポイントに関するすべての情報を提供する「よく知られた設定」を取得するよう試みます。例) Googleの場合 - 基本サービスのURLは「https://accounts.google.com/」です。このURLに「.well-known/openid-configuration」 を付加してhttps://accounts.google.com/.well-known/openid-configurationにあるサービス説明文を閲覧できます。説明文にはこのサービスの設定を自動的に完了させるために必要な情報すべてを含みます。これはOpen ID connectに準拠したサービスであればどれでも動作します。

Open Badge Connect API

Open Badge Connect APIはIMS Global社により策定されたOAuth 2ベースサービスの標準化および相互運用性を提供するための仕様です。イシュアに「基本サービスURL」が入力された場合、Moodleはこのサービスの設定を完了するために必要なエンドポイントに関するすべての情報を提供する「よく知られた設定」(well-known/badgeconnect.json) を取得するよう試みます。さらにクライアントIDおよびシークレットが与えられていない場合、それらを取得するために登録エンドポイントがコールされます (そして管理者に安全な時間および労力を提供します)。 例) IMS Globalテストプラットフォームの場合、基本サービスのURLは「https://dc.imsglobal.org/」です。私たちはこのURLに「.well-known/badgeconnect.json」を追加してこのサービスのセットアップを自動的に完了するために必要なすべての情報 (エンドポイント、クライアントIDと秘密、画像 ...) を含むサービスの説明を確認できます。

ユーザフィールドマッピング

OAuth 2サービスに関して私たちが知るべき他の情報はユーザ情報をMoodleのユーザフィールドにマッピングする方法です。イシュア用のユーザフィールドマッピングのリストにユーザ情報を追加することによりマッピングします。Open ID Connectサービス用のマッピングは標準的なものでOpen IDに準拠したサービスをセットアップする際に自動作成されます。新しいアカウントを作成する場合、Moodleはユーザプロファイルのフィールドをインポートするためにこの情報を使用します。最も重要なユーザフィールドのマッピングはOAuth 2ログインに関連するMoodleアカウントを識別するために使用されるユーザ名およびメールアドレスです。


新しいイシュアサービスをどのように実装するのか?

いかなるOAuth2サービスにおいてもlib/classes/oauth2/service/フォルダにディスカバリシステムから拡張されたクラス (core\oauth2\discovery\base_definition) およびcore\oauth2\service\issuer_interfaceの実装が必要です:

  • ディスカバリシステムではエンドポイントを取得する方法を示します。
  • イシュアインタフェースにはいくつかの共通メソッドがあり、エンドポイントを初期化または発見するためlib/classes/oauth2/api.phpからコールされます。
class google extends openidconnect implements issuer_interface {
[...]

class imsobv2p1 extends imsbadgeconnect implements issuer_interface {
[...]


OAuth 2イシュアを設定しました - コード内でどのように使えばよいですか?

まずどのイシュアを利用して認証するかをOAuthイシュアが提供する設定情報を利用したいプラグインでは決定する必要があります。これは通常、管理者が設定されたイシュアのリストから選択できるようにする設定追加で実現できます。例えば「Google Drive」リポジトリのようなものです。似たようなOAuthイシュアの複数設定も可能です。例えば公開されているGoogleのイシュアおよび特定のドメインに限定されたイシュアがあります。使用したいイシュアが分かった場合、私たちはそのIDを使用してAPIに対してリクエストできるイシュアクラス (IssuerClient) を取得できます。

// IDからイシュアを取得します。
$issuer = \core\oauth2\api::get_issuer($issuerid);
// イシュアからOAuthクライアントを取得します。
$client = \core\oauth2\api::get_user_oauth_client($this->issuer, $returnurl, $scopes);

コードドキュメントに書かれている内容に拘わらず、クライアントが認証されているかどうかを確認して、認証されていない場合はログインするようユーザをリダイレクトするのがベストです。

if (!$client->is_logged_in()) {
    redirect($client->get_login_url());
}

戻りURLとは何ですか?

これはあなたを現在のページから元のページに戻すためのURLです。OAuthの仕組みはOAuthクライアントを取得するための呼び出しで私たちに必要なスコープすべてを持つ有効なセッションがあるかどうか確認するというものです。私たちにセッションがない場合、直ちにOAuthログインページにリダイレクトされます。ログインできた場合、Moodleの「returnurl」にリダイレクトされてOAuthクライアントを取得するために同じ呼び出しが実行されます - 今回は有効なセッションがあるため、クライアントが返されます。returnurlにはパラメータの1つとしてsesskeyを含む必要があります。

スコープとは何ですか?

これは「パーミッショングラント」(パーミッション許可) と名付けられユーザは承諾を求められます。 例えば「email」はあなたがログインしているアカウントのメールアドレスをMoodleが確認できるようにするスコープです。要求された各パーミッションはその意味の説明とともにユーザに表示されるため、ユーザはMoodleにこのレベルのアクセスを「許可」にする必要があります - 許可しない場合は操作をキャンセルしてください。一度に必要以上のスコープを要求せずにMoodleの異なる機能で使用されそうなスコープを段階的に追加要求することが最良の方法です。例えばMoodleにログインする場合、私たちはユーザの基本プロファイルおよびメールアドレスへのアクセスを要求する必要があるだけです。リポジトリにアクセスする場合 - 私たちはユーザのファイルへの読み込み/書き込みアクセス権を要求する必要があります。私たちはOAuthクライアントクラスを作成する度にOAuthクライアントインスタンスで使用するスコープをリストアップします。もしユーザが要求したスコープの一部しか承認しない場合、追加アクセスレベルを承認するための同意画面にリダイレクトされます。

それで、OAuthクライアントで何ができますか?

リクエストを作成しましょう! このクラスはmoodle curlクラスを継承していますが、各リクエストには自動的に認証情報を含めます。これは$client->get()または$client->post()のような標準関数を使用して手動で残りのAPI関数を呼び出せることを意味します。またこのクラスはIPアドレスブラックリストおよびプロキシ設定のような設定済みMoodleセキュリティ設定を尊重します。

API関数を簡単に呼び出すには?

外部のrest apiを使いやすくラップするためのヘルパ関数が含まれた抽象クラス\coreauth2restが存在します。使用するには自分のプラグインでサブクラスを作成した上で「get_api_functions()」メソッドを定義してください。


* Google Drive Rest API.
*
* @package    fileconverter_googledrive
* @copyright  2017 Damyon Wiese
* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace fileconverter_googledrive;

defined('MOODLE_INTERNAL') || die();

/**

* Google Drive Rest API.
* 
* @copyright  2017 Damyon Wiese
* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

class rest extends \core\oauth2\rest {

   /**
    * Define the functions of the rest API.
    *
    * @return array Example:
    *  [ 'listFiles' => [ 'method' => 'get', 'endpoint' => 'http://...', 'args' => [ 'folder' => PARAM_STRING ] ] ]
    */
   public function get_api_functions() {   
       return [
           'create' => [
               'endpoint' => 'https://www.googleapis.com/drive/v3/files',
               'method' => 'post',
               'args' => [
                   'fields' => PARAM_RAW   
               ],
               'response' => 'json'
           ],
           'delete' => [
               'endpoint' => 'https://www.googleapis.com/drive/v3/files/{fileid}',
               'method' => 'delete',
               'args' => [
                   'fileid' => PARAM_RAW
               ],       
               'response' => 'json'
           ],
       ];
   }

}

</syntaxhighlight>

この例では外部APIに「create」および「delete」の2つの関数を定義しています。これらの関数を呼び出し時には使用するhttpメソッドおよびパラメータのリストを指定します。また、これらの関数が「json」を返すことも指定しています。 これはRESTクラスがjsonレスポンスを自動的にデコードしてオブジェクトに変換することを意味します。各関数の呼び出しURLにはパラメータを含めることができます (中括弧でマークされています)。これらは関数に引数として渡される際に置き換えられます。残りの引数はクエリパラメータとして追加されます。

このクラスを使うには - 私たちはコンストラクタにoauth2クライアントを渡した後、「call」メソッドを使ってAPIから関数を呼び出します。


$service = new \fileconverter_googledrive\rest($client);

$params = ['fileid' => $fileid];

$service->call('delete', $params);

ユーザがログインしていない場合、 (スケジュールタスク等から) API関数を呼び出すにはどのようにすればよいですか?

MoodleではあなたがOAuthイシュアのいずれかに「システムアカウント」を接続できます。これは任意です - したがって、このレベルのアクセスに依存する機能を有効にする前にシステムアカウントが接続されていることを確認してください。

if ($issuer->is_system_account_connected()) {
    // Rock and roll.
}

システムアカウントが接続されている場合、それを使って認証されたoauthクライアントを取得できます (リダイレクトは関係ありません)。

$client = \core\oauth2\api::get_system_oauth_client($issuer);

このクライアントはMoodleシステムユーザとしてAPIにアクセスできるようになります。

あなたのコードがこのAPIで追加ログインスコープを使用する場合、Moodle管理者がシステムアカウントに接続時にすべてのスコープに同意および承諾できるようにコールバック関数で使用するすべてのスコープをリストする必要があります。

**
 * システムアカウントに必要なスコープを取得するためのコールバックです。
 *
 * @param \core\oauth2\issuer $issuer
 * @return string
 */
function fileconverter_googledrive_oauth2_system_scopes(\core\oauth2\issuer $issuer) {
    if ($issuer->get('id') == get_config('fileconverter_googledrive', 'issuerid')) {
        return 'https://www.googleapis.com/auth/drive';
    }
    return '';
}

システムアカウントの仕組みはMoodle管理者がこのアカウントでログインした後、「サイト管理 -> サーバ -> OAuth 2サービス」ページから権限を受け入れてシステムアカウントに「接続」することです。システムアカウントで受け入れなければならない許可の1つはオフラインアクセスです。これはMoodleが受け取ったリフレッシュトークンをイシュアに対して保存できることを意味します。私たちがログインしているOAuthクライアントを取得する必要がある場合、ログインすることなくリフレッシュトークンとアクセストークンを直接交換できます。リフレッシュトークンはスケジュールタスクによって更新されます。また、リフレッシュトークンが期限切れとなることはありません。