開発:OAuth 2 API

提供:MoodleDocs
移動先:案内検索

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クライアントを取得する必要がある場合、ログインすることなくリフレッシュトークンとアクセストークンを直接交換できます。リフレッシュトークンはスケジュールタスクによって更新されます。また、リフレッシュトークンが期限切れとなることはありません。