書くこと
-
openapi-generator
のdart-dio-next
で生成したコードでAuthorizationヘッダーにBearerトークンを指定する方法 - 自動生成されるBearerトークンを指定処理のソースコードの解説
書かないこと
- APIのパスを定義した完全なOpenAPI定義について
-
openapi-generator
の実行環境について - OpenAPIについて
openapi-generatorについて
OpenAPI v3の 定義からソースコードを自動生成するツール。
今回使うgenerateテンプレートはdart-dio-next
というdio
パッケージを使ったDart
のソースコード
OAS定義
公式リファレンスに従いOASを定義していきます。
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
openapi-generator
実行
細かいパラメーターは各環境に合わせてください
$ openapi-generator generate -i openapi.yml -g dart-dio-next
API呼び出しとトークン設定
自動生成したパッケージのクラスに対してsetBearerAuth
を呼び出し第一引数にOASのsecuritySchemes
で指定したスキーマの名前'bearerAuth'
を、第二引数にトークンの値を設定します。
final client = HttpClient();
client.setBearerAuth('bearerAuth', 'abc');
詳細
出力されるdart パッケージのlib/api.dart
に以下のようにBearer tokenを設定する関数が定義されています。
void setBearerAuth(String name, String token) {
if (this.dio.interceptors.any((i) => i is BearerAuthInterceptor)) {
(this.dio.interceptors.firstWhere((i) => i is BearerAuthInterceptor) as BearerAuthInterceptor).tokens[name] = token;
}
}
この関数ではBearerAuthInterceptor
のtokens
メンバに値を代入します。
setBearerAuth('bearerAuth', 'abc')
としたので'bearerAuth'
keyに'abc'
valueを代入しています。
実際にリクエストを行う際BearerAuthInterceptor
のonRequest
でインターセプト処理が行われます。
lib/auth/bearer_auth.dart
は以下のように定義されています。
class BearerAuthInterceptor extends AuthInterceptor {
final Map<String, String> tokens = {};
@override
void onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) {
final authInfo = getAuthInfo(options, (secure) => secure['type'] == 'http' && secure['scheme'] == 'bearer');
for (final info in authInfo) {
final token = tokens[info['name']];
if (token != null) {
options.headers['Authorization'] = 'Bearer ${token}';
break;
}
}
super.onRequest(options, handler);
}
}
getAuthInfo
関数を呼び出してその結果をループし、tokens
に格納されている前述したBearer tokenを 取り出してヘッダーに設定しています
getAuthInfo
の 引数に定義されている以下の関数はOASで定義したsecuritySchemes
を取得する関数です。
(secure) => secure['type'] == 'http' && secure['scheme'] == 'bearer'`
そのため、前述したOASでsecuritySchemes
を定義していないとこのメソッドは意図した通りに動きません。
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
getAuthInfo
関数はlib/auth/auth.dart
は以下のように定義されています。
abstract class AuthInterceptor extends Interceptor {
/// Get auth information on given route for the given type.
/// Can return an empty list if type is not present on auth data or
/// if route doesn't need authentication.
List<Map<String, String>> getAuthInfo(RequestOptions route, bool Function(Map<String, String> secure) handles) {
if (route.extra.containsKey('secure')) {
final auth = route.extra['secure'] as List<Map<String, String>>;
return auth.where((secure) => handles(secure)).toList();
}
return [];
}
}
OASのsecuritySchemes
で指定した値をリストで取得します。bearerFormat
を扱う機能は提供されていないようでリストから除外されています。
[{type: http, scheme: bearer, name: bearerAuth}]
環境
- openapi-generator-cli v5.3.1
- Dart SDK version: 2.16.0