20200104のNode.jsに関する記事は5件です。

npm コマンドでグローバルインストールされたパッケージを表示する

次のコマンドを実行することで、グローバルインストールされたパッケージが表示される。

npm ls -g --depth=0
  • npm ls : インストールされているパッケージを表示する
  • npm ls -g : グローバルインストールされているパッケージをする
  • npm ls --depth=0 : トップレベルのパッケージのみを表示する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

試しに「OpenID Connect Provider Certification」を通してみた

以前、なんちゃってOpenID Connectサーバを立ち上げました。( なんちゃってOAuth2/OpenID Connectサーバを自作する )

それはそれで役に立っているのですが、OpenID Connectに準拠しているかどうかを確認するためのTest Suite があったので、物は試しで通してみました。
結果は、散々でした。Optional機能は実装していないので当然ではありますが。

Conformance Testing for OPs
 https://openid.net/certification/testing/

テストの準備

まずは、準備として、テスト対象のエンドポイントのURLやサポートする機能を指定します。

 https://op.certification.openid.net:60000/

image.png

New ボタンを押下します。

image.png

Issuerに、サーバで生成するトークンに含めるissの値を指定します。
Response Typeとして「code」を選択しました。

最後に、「Create」ボタンを押下します。

次は、各エンドポイントなどを指定します。

image.png

以下の値を指定することで、テストを開始できました。

・contact_email : 適当な値
・authorization_endpoint : 認証エンドポイント
・jwks_uri : 署名を検証するための公開鍵のエンドポイント
・token_endpoint : トークンエンドポイント
・userinfo_endpoint : USERINFOエンドポイント
・client_id : 適当な値
・client_secret : 適当な値

最後に、「Save & Start」ボタンを押下すると、テスト用のページに進みます。

image.png

いざ、テスト実施

左側の列にある再生ボタンを押下していくと、それぞれテストが実施されます。
結果はこんな感じです。

image.png

まあ、実装を手抜きしているので当然ですね。
右側の列にある「!」マークのボタンを押下すれば、実行経過やエラー理由が確認できます。

エラーとなった理由を列挙しておきます。

(OP-Response-Missing)
・エラーメッセージを返すべきだが、HTTPエラーステータスが返ってきている。Swaggerで必須パラメータを指定しているがそれがないため

(OP-ClientAuth-SecretPost-Static)
(OP-claims-essential)
(OP-nonce-code)
(OP-prompt-none-LotLoggedIn)
(OP-Req-acr_values)
(OP-Req-login_hint)
(OP-Req-max_age=1)
(OP-Req-max_age=100000)
・OpenID Connectの仕様上Optionalな機能であり、対応していません。

(OP-redirect_uri-NotReg)
・リダイレクトURIをチェックしていないため(手抜き実装)

(OP-Oauth-2nd)
(OP-OAuth-2nd-30s)
(OP-OAuth-2nd-Revokes)
・認可コードの期限チェックや利用済みのチェックをしていないため(手抜き実装)

(参考) OpenID Connect Core 1.0 日本語訳
 http://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

終わりに

なんちゃっての実装でしたが、こうしてやって実施してみると、すんなり確認が通ってよかったよかった。

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS+NodeJSでサーバレスな環境構築④

はじめに

今回は前回の続きで、DELETE(対象ユーザーの削除), GET(全ユーザーの取得) PATCH(対象ユーザーの更新)を作っていきます。

DELETE(対象ユーザーの削除)

指定されたidを元に、対象のユーザーが削除されるようにしていきます。

Lambda関数の作成と設定

スクリーンショット 2020-01-04 15.20.08.png

ソース

index.js
'use strict';
const AWS = require('aws-sdk');
const myRegion = "us-east-2";

AWS.config.update({ region: myRegion});

exports.handler = async (event, context) => {
  const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion});

  let responseBody = "";
  let statusCode = 0;

  const { id } = event.pathParameters;

  const params = {
    TableName: "Users",
    Key: {
      id: id
    }
  };

  try {
    const data = await documentClient.delete(params).promise();
    responseBody = JSON.stringify(data);
    statusCode = 204;
  } catch (err) {
    responseBody = `Unable to delete user: ${err}`;
    statusCode = 403;
  }

  const response = {
    statusCode: statusCode,
    headers: {
      "Content-Type": "application/json"
    },
    body: responseBody
  };

  return response;
};

メソッド作成と設定

スクリーンショット 2020-01-03 23.23.55.png
スクリーンショット 2020-01-03 23.32.59.png

テスト実行と確認

テストボタン
スクリーンショット 2020-01-03 23.42.51.png
削除されていることを確認
スクリーンショット 2020-01-04 15.36.19.png

GET(全ユーザーの取得)

GETメソッドを実行したとき、全ユーザーが取得されるようにする。

Lambda関数の作成と設定

スクリーンショット 2020-01-04 11.47.15.png
ソース

index.js
'use strict';
const AWS = require('aws-sdk');
const myRegion = "us-east-2";

AWS.config.update({ region: myRegion});

exports.handler = async (event, context) => {
  const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion});

  let responseBody = "";
  let statusCode = 0;

  const params = {
    TableName: "Users"
  };

  try {
    const data = await documentClient.scan(params).promise();
    responseBody = JSON.stringify(data);
    statusCode = 200;
  } catch (err) {
    responseBody = `Unable to get users: ${err}`;
    statusCode = 403;
  }

  const response = {
    statusCode: statusCode,
    headers: {
      "Content-Type": "application/json"
    },
    body: responseBody
  };

  return response;
};

メソッド作成と設定

スクリーンショット 2020-01-04 11.48.16.png
スクリーンショット 2020-01-04 11.49.15.png

 テスト実行と確認

何も入力せつ、テストボタン。
スクリーンショット 2020-01-04 15.50.36.png

PATCH(対象ユーザーの更新)

PATCHメソッドを実行したとき、対象のユーザが更新されるようにする。

Lambda関数の作成と設定

スクリーンショット 2020-01-04 12.11.31.png

メソッド作成と設定

スクリーンショット 2020-01-04 12.12.22.png
以下のように設定、赤枠使うのが面倒になったので察して
スクリーンショット 2020-01-04 12.14.32.png

 テスト実行と確認

スクリーンショット 2020-01-04 12.20.18.png

リクエスト本文
{
    "id": "02",
    "firstname": "update_firstname",
    "lastname": "update_lastname"
}

更新されることを確認
スクリーンショット 2020-01-04 12.24.17.png

終わりに

これでサーバレスでREST APIを使ったCRUD作成の環境構築をしました。
次はAPI Gateway+Lambda(NodeJS)+S3を組み合わせていこうと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS+NodeJSでサーバレスな環境構築③

はじめに

前回の記事ではDynamoDBのテーブルと項目作成、Lambda関数で使うロールやインラインポリシーの設定を行いました。今回はその続きで、API Gateway(REST APIでCRUD実装)をトリガーにし、Lambda(NodeJS)関数呼び出して、DynamoDBに参照や更新をできるようにします。
表現等が不適切の場合はご指摘いただければ、幸いです。
※サーバレスに関してよくわからない方は、こちらをご覧いただければと思います。

アーキテクチャ図

serverless.png

流れ

  • ソースで直接(Api gatewayを使わず)参照や更新ができるかを確認
  • POST(ユーザーの登録)
    • domain.com/users/{id}
  • DELETE(対象ユーザーの削除)
    • domain.com/users/{id}
  • GET(全ユーザーの取得)
    • domain.com/users
  • PATCH(対象ユーザーの更新)
    • domain.com/users/{id}

ソースで直接(Api gatewayを使わず)参照や更新ができるかを確認

まずはLambda(NodeJS)でDynamoDBテーブルが参照・更新できるか確認
Lambdaダッシュボード>関数の作成>一から作成>以下の通り入力>関数の作成ボタン
※既存のロール設定は前回の記事で作成したものを使用しています。
スクリーンショット 2020-01-03 19.43.16.png

データの参照ができるよう、ソース編集
こちらのリファレンスを参考にしました。

index.js
'use strict';

const AWS = require('aws-sdk');
const myRegion = "us-east-2";

AWS.config.update({ region: myRegion});

exports.handler = async (event, context) => {
  const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion});

  //読込用のデータ
  const params1 = {
    TableName: "Users",
    Key: {
      id: "01"
    }
  };
  //書込用のデータ
  const params2 = {
    TableName: "Users",
    Item: {
      id: "02",
      firstname: "first02",
      lastname: "last02"
    }
  };

  try {
    const readData = await documentClient.get(params1).promise();
    const writeData = await documentClient.put(params2).promise();
    console.log(readData);
    console.log(writeData);
  } catch (err) {
    console.log(err);
  }
};

⚠️ 必ず、DynamoDBとLambdaは同じリージョンで作成するように気をつける。また上記ソースのmyRegion変数値も合わせるように気をつける。いずれが満たない場合、AccessDeniedExceptionという意味不明なエラーが発生する可能性があります。

テストイベントの設定>テストボタン>取得結果が表示されれば、OK
スクリーンショット 2020-01-03 19.58.10.png

DynamoDBにデータ作成されていることを確認
ちなみに、params2でidをそのまま、firstnameやlastnameを変更すると更新される仕様です。
スクリーンショット 2020-01-03 20.00.54.png

API Gatewayトリガー追加と設定

API Gatewayダッシュボード>APIを作成ボタン>REST APIの構築ボタン(Privateじゃない方)
以下のように入力>APIの作成ボタン
スクリーンショット 2020-01-03 20.32.20.png

エッジ最適化について(AWS公式より引用)

エッジ最適化 API は、API ゲートウェイによって作成および管理される CloudFront ディストリビューション経由でアクセスするエンドポイントです。以前は、エッジ最適化 API は、API ゲートウェイを使用して API を作成する際のデフォルトオプションでした。

参考記事
0からREST APIについて調べてみた
エッジ最適化について説明

リクエスト、レスポンスマッピングのモデルを作成及び設定

参考
モデル名、コンテンツタイプ、スキーマ(ソース)を設定します。
スクリーンショット 2020-01-03 21.41.42.png

スキーマのソース
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "UsersInputModel",
  "type": "object",
  "properties": {
      "id": {"type": "string"},
      "firstname": {"type": "string"},
      "lastname": {"type": "string"}
  }
}

アクション>リソースの作成
リソースは2つ作成します。
スクリーンショット 2020-01-03 21.13.48.png
スクリーンショット 2020-01-03 21.15.55.png

POSTメソッド実装(ユーザーの登録)

ここではAPI GatewayでPOSTメソッドを作成して、レコードが登録されるかを確認する。

API Gatewayと紐付けるLambda関数を作成と設定

関数名はputUsersで、その他の設定は前回と一緒(察して)(冒頭のLambda関数作成のスクリーンショット参照)

以下のソースを貼り付けます。
DynamoDBの構成に関しては、こちらの記事を参考にしてください。(DynamoDBテーブルの作成部分)

index.js
'use strict';
const AWS = require('aws-sdk');
const myRegion = "us-east-2";

AWS.config.update({ region: myRegion});

exports.handler = async (event, context) => {
  const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion});

  let responseBody = "";
  let statusCode = 0;

  const { id, firstname, lastname } = JSON.parse(event.body);

  const params = {
    TableName: "Users",
    Item: {
      id: id,
      firstname: firstname,
      lastname: lastname
    }
  };

  try {
    const data = await documentClient.put(params).promise();
    responseBody = JSON.stringify(data);
    statusCode = 201;
  } catch (err) {
    responseBody = `Unable to put user ${err}`;
    statusCode = 403;
  }

  const response = {
    statusCode: statusCode,
    headers: {
       "Content-Type": "application/json"
    },
    body: responseBody
  };

  return response;
}

POSTメソッド作成と設定

アクション>メソッドの作成
スクリーンショット 2020-01-03 21.24.17.png

メソッドリクエストの設定
モデルの追加には上記の作成したモデルを追加する
スクリーンショット 2020-01-03 21.46.26.png

API Gatewayで確認テスト

下の方にテストボタンあるので、それを押すとテスト結果(ログも含めて)画面右側に表示されると思います。
スクリーンショット 2020-01-03 22.12.05.png

スクリーンショット 2020-01-03 22.23.42.png

リクエスト本文
{
    "id": "03",
    "firstname": "first03",
    "lastname": "last03"
}

テストステータスで201が返ってこれば、成功みたいです。
⚠️ ちなみに本来DynamoDBテーブルにない項目論理名(例えばfirstnameではなく、あえてnickname)をリクエスト本文に設定された場合、問題なくテスト処理は実行されます。対象のレコードfirstnameには空白が入る仕様になっています。

DynamoDBテーブルにレコードが作成されていることを確認
スクリーンショット 2020-01-03 22.27.09.png

to be continued

ちょっと長くなりそうなので、続きを次回出します。
あとはDELETE(対象ユーザーの削除), GET(全ユーザーの取得) PATCH(対象ユーザーの更新)のメソッドを作成して、最後までCRUD機能を実装していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

node.jsでAbemaをダウンロードする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む