AbstractAuthProtocol: verify()
リクエストに付与されている認証情報を検証して、リクエストを受諾するか棄却するかを判定します。
この関数は非同期関数です。
構文
authProtocol.verify(request) => Promise<{ ok[, status][, reason][, scheme] }>
引数
-
request:http.IncomingMessage|{ method, path, body, headers, query }検証する対象のリクエストです。オブジェクトだった場合、以下のプロパティを持ちます:
-
method:stringメソッド名を表す文字列です。
-
path:stringリクエストされたパスを表す文字列です。
-
body:string|Buffer|{ [key: string]: number | string | boolean | object | Uint8Array | null }リクエストのボディです。Content-Type リクエストヘッダの値によって型が異なります。
Content-Type リクエストヘッダの値 -- -- text/*stringapplication/json{ [key: string]: number | string | boolean | object | null }multipart/form-data{ [key: string]: number | string | boolean | object | Uint8Array | null }application/x-www-urlencoded{ [key: string]: string }その他のコンテンツ形式 Buffer -
headers:{ [header_name: string] : { value, params }[] }リクエストのヘッダをパースしたオブジェクトです。
プロパティ名
header_nameは小文字変換されたリクエストヘッダ名(例:"content-type")です。各プロパティ値は対応するリクエストヘッダ行をまとめたの配列であり、配列成分は単一のヘッダ行を表しています。
各ヘッダ行は専用のパーサによって
valueとparamsの2つプロパティを持つオブジェクトに変換されます。-
value:stringそのヘッダの主要な 値 を表す文字列であり、常に設定されます。
-
params:{ [param_name: string]: string }?そのヘッダに許される必須でないパラメタが設定されます。パラメタの指定がなかった場合は
paramsプロパティ自体がnullとなります。
-
-
query:{ [param_name: string]: any }リクエストのクエリパラメタです。
-
返値: Promise<({ ok, status, reason, scheme })>
検証結果です。
ok:boolean--- 検証に成功した場合はtrue、そうでなければfalseです。。status:number|undefined--- 検証に失敗した場合のレスポンスのステータスコードです。reason:any|undefined--- 検証に失敗した理由です。scheme:string|undefined--- 検証を実行した認証方式名です。
例
const { IncomingMessage } = require("node:http");
const { Router } = require("@suredesigns/alier/Router");
const { WebApi } = require("@suredesigns/alier/WebApi");
const { AbstractAuthProtocol } = require("@suredesigns/alier/Auth");
/* 何かの認証プロトコルの実装 */
class MyAuthProtocol extends AbstractAuthProtocol {
async verify(request) {
if (request === null || typeof request !== "object") {
return {
ok : false,
scheme: this.scheme,
status: 400,
reason: {
error : "invalid_request",
error_description: "malformed request"
}
};
}
if (request instanceof IncomingMessage) {
/* IncomingMessage 用の処理 */
const authz = request.headers.authorization;
if (authz == null) {
return {
ok : false,
scheme: this.scheme,
status: 401,
reason: {
error : "invalid_token",
error_description: "unauthorized"
}
};
}
const { scheme, token68, params } = /* authz を scheme, token68, params に分割 */;
/* Authorization ヘッダの検証の実装 */
if (/* 認証成功条件 */) {
return { ok: true };
} else if (/* 401 Unauthorized を返す条件 */) {
return {
ok : false,
scheme: this.scheme,
status: 401,
reason: {
error : "invalid_token",
error_description: "unauthorized"
}
};
} else if (/* 403 Forbidden を返す条件 */) {
return {
ok : false,
scheme: this.scheme,
status: 403,
reason: {
error : "insufficient_scope",
error_description: "permission denied"
}
};
} else {
return {
ok : false,
scheme: this.scheme,
status: 404,
reason: {
error : "invalid_request",
error_description: "bad request"
}
};
}
} else {
/* 一般の非 null オブジェクト用の処理 */
const authz = request.headers.authorization?.[0];
if (authz == null) {
return {
ok : false,
scheme: this.scheme,
status: 401,
reason: {
error : "invalid_token",
error_description: "unauthorized"
}
};
}
const { scheme, token68, params } = /* authz を scheme, token68, params に分割 */;
/* 以下同上 */
}
}
}
const my_protocol = MyAuthProtocol();
// 認証処理を実装した WebApi クラスのインスタンス
// このクラスは GET メソッドを受け付ける、Web認証を要求する WebApi を生成する。
// MyAuthProtocol で実装した verify() は WebApi の基底クラス WebEntity が提供する verify() から呼び出される。
const my_api = new class MyApi extends WebApi {
constructor() {
super({
path : "/api/which/requires/authorization",
authProtocols: [ my_protocol ]
});
}
async get(params) { /* GET メソッドの実装 */ }
};
// Router を生成; リクエストおよびレスポンスの処理を行う
donst router = new Router();
// WebApi を Router に登録する
router.enable(my_api);
// リクエストの受付を開始する
router.listen(/* 使用可能なポート番号 */);
解説
関数 verify() は WebEntity::verify() 関数の中で呼び出されます。
WebEntity のコンストラクタ引数 o.authProtocols には複数の AbstractAuthProtocol インスタンスを含めることができますが、どの認証プロトコルの実装が使われるかは、Authorization リクエストヘッダのスキーム名が認証プロトコルのプロパティ scheme に一致するかどうかで判断されます。スキーム名が一致したプロトコルに対して、そのプロトコルが実装する関数 verify() が呼び出されます。