OAuth2

OAuth2

この例では、gRPC で OAuth2 を使用して、ユーザーの代わりに認証済み API 呼び出しを行う方法を示します。

この例を実行することで、Objective-C gRPC API を使用して以下の方法を学ぶことができます。

  • RPC が開始される前に、リモートコールオブジェクトを初期化および設定する。
  • コールにリクエストメタデータ要素を設定する。これは、HTTP リクエストヘッダーと意味的に同等です。
  • コールからレスポンスメタデータを読み取る。これは、HTTP レスポンスヘッダーおよびトレーラーと同等です。

基本チュートリアルgRPC の概要 に示されているように、Objective-C クライアントライブラリを使用して gRPC API 呼び出しを行うための基本的な知識があり、*アクセストークン* のような OAuth2 の概念に精通していることを前提としています。

サンプルコードとセットアップ

サンプルソースについては、gprc/examples/objective-c/auth_sample を参照してください。 例をダウンロードするには、次のコマンドを実行してこのリポジトリをクローンします。

$ git clone -b v1.62.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
$ cd grpc
$ git submodule update --init

次に、現在のディレクトリを examples/objective-c/auth_sample に変更します。

$ cd examples/objective-c/auth_sample

この例は、2 つのビューを持つシンプルなアプリケーションです。最初のビューでは、Google の iOS サインインライブラリ の OAuth2 フローを使用して、ユーザーがサインインおよびサインアウトできます。(この例では、呼び出すテスト gRPC サービスが Google アカウントの認証情報を想定しているため、Google のライブラリが使用されていますが、gRPC と Objective-C クライアントライブラリのいずれも特定の OAuth2 プロバイダーに関連付けられていません)。 2 番目のビューは、最初のビューで取得したアクセストークンを使用して、テストサーバーへの gRPC リクエストを行います。

他の Objective-C の例と同様に、CocoaPods と、クライアントライブラリコードを生成するための関連ツールもインストールしておく必要があります。 後者は、こちらのセットアップ手順 に従って入手できます。

試してみよう!

サンプルアプリを試すには、まず CocoaPods に .proto ファイルのクライアントライブラリを生成してインストールしてもらいます。

$ pod install

(これにより OpenSSL がコンパイルされる必要がある場合があります。CocoaPods がコンピューターのキャッシュに OpenSSL をまだ持っていない場合は、約 15 分かかります)。

最後に、CocoaPods によって作成された Xcode ワークスペースを開き、アプリを実行します。

最初のビュー SelectUserViewController.h/m は、Google アカウントでサインインし、「gRPC-AuthSample」アプリに次の権限を与えるように求めます。

  • メールアドレスを表示する。
  • 基本的なプロフィール情報を表示する。
  • 「Zoo サービスへのアクセスのテストスコープ」。

スコープ https://www.googleapis.com/auth/xapi.zoo に対応するこの最後の権限は、実際の機能を付与しません。テストにのみ使用されます。 いつでもログアウトできます。

2 番目のビュー MakeRPCViewController.h/m は、https://grpc-test.sandbox.google.com のテストサーバーに gRPC リクエストを行い、リクエストとともにアクセストークンを送信します。 テストサービスは単にトークンを検証し、レスポンスにトークンが属するユーザーと、トークンがアクセス権を与えるスコープを書き込みます。 (クライアントアプリケーションはすでにこれらの 2 つの値を知っています。すべてが期待どおりに進んだことを確認する方法です)。

次のセクションでは、MakeRPCViewController での gRPC 呼び出しの実行方法をステップバイステップで説明します。 完全なコードは、MakeRPCViewController.m で確認できます。

アクセストークンを使用したコールの作成

認証付き呼び出しを行うには、まず GRPCCallOptions オブジェクトを初期化し、アクセストークンで設定する必要があります。

GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.oauth2AccessToken = myAccessToken;

次に、この呼び出しオプションオブジェクトを使用して呼び出しを作成して開始する必要があります。 次のような proto サービス定義があるとします。

option objc_class_prefix = "AUTH";

service TestService {
  rpc UnaryCall(Request) returns (Response);
}

すでに使い慣れている unaryCallWithMessage:responseHandler:callOptions: メソッドは、AUTHTestService クラス用に生成されます。

- (GRPCUnaryProtoRPC *)unaryCallWithMessage:(AUTHRequest *)message
                            responseHandler:(id<GRPCProtoResponseHandler>)responseHandler
                                callOptions:(GRPCCallOptions *)callOptions;

このメソッドを使用して、リクエストオプションオブジェクトを使用して RPC オブジェクトを生成します。

GRPCUnaryProtoRPC *rpc = [client unaryCallWithMessage:myRequestMessage
                                      responseHandler:myResponseHandler
                                          callOptions:options];

その後、次のように、このオブジェクトによって表される RPC を後でいつでも開始できます。

[rpc start];

アクセストークンを提供する別の方法

RPC オブジェクトが作成される前に GRPCCallOptionsoauth2AccessToken オプションを設定するのではなく、別の方法として、ユーザーが呼び出し開始時にアクセストークンを提供できるようにする方法があります。

この方法を使用するには、まず GRPCAuthorizationProtocol プロトコルに準拠するクラスをプロジェクトに作成します。

@interface TokenProvider : NSObject<GRPCAuthorizationProtocol>
...
@end

@implementation TokenProvider

- (void)getTokenWithHandler:(void (^)(NSString* token))handler {
  ...
}

@end

RPC オブジェクトを作成するときは、このクラスのインスタンスを呼び出しオプション authTokenProvider に渡します。

GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.authTokenProvider = [[TokenProvider alloc] init];
GRPCUnaryProtoCall *rpc = [client unaryCallWithMessage:myRequestMessage
                                       responseHandler:myResponseHandler
                                           callOptions:options] start];
[rpc start];

呼び出しが開始されると、コールバック handler を使用して TokenProvider インスタンスの getTokenWithHandler: メソッドが呼び出され、コールバックが待機されます。 TokenProvider インスタンスは、いつでもハンドラーを呼び出して、この呼び出しのトークンを提供し、呼び出しプロセスを再開できます。