0
0

More than 1 year has passed since last update.

Node.jsのSession StoreとしてIBM Cloudantを使ってみる

Posted at

はじめに

Webアプリケーションではsessionを用いることが多いと思いますが、前回の記事で触れたようにexpress-sessionのデフォルトの実装を用いる場合はメモリにsessionの情報を保持するため、アプリケーションの再起動等で情報は失われてしまいますし、アプリケーションのインスタンスが複数ある場合などに問題が起きるため、プロダクションでは外部のデータストアを用いることになると思います。この用途にはRedisが使われることが多いようですが、IBM Cloudでは(2022年1月現在)RedisにLiteプランがないため、最小構成でもそこそこのコストがかかることになり、実験には向かないようです。そこで今回はIBM Cloudantをsessionのストアとして用いることを検討してみます。

IBM Cloudant

IBM CloudantはJSON document databaseです。IBM Cloudのコンソールから検索するなどしてトップページを開き、Liteプランのインスタンスを1つプロビジョンします。

スクリーンショット 2022-01-04 23.47.47.png

プロビジョンが完了したら管理画面に入れるようになります。サービス資格情報から接続用の資格情報を作成しておきます。

スクリーンショット 2022-01-04 23.54.06.png

Session情報を保存するデータベースとしてsessionsを作成しておきます。管理画面のLaunch DashboardをクリックしてCloudantの管理画面を開き、Create Databaseのボタンからデータベースを作成できます。

スクリーンショット 2022-01-05 0.04.52.png

Node.jsでの構成

まずは connect-cloudant-storeをインストールします。

$ npm install connect-cloudant-store --save

前回のApp IDのcredentialsと同様、Cloudantのcredentialsもローカルではlocal.jsonから、クラウド環境では環境変数から指定するように構成します。まずlocal.jsoncloudantというキーで先ほどの資格情報をペーストしておきます。クラウド環境用にcustom-environment-variables.jsonへも追加しておきます。

config/custom-environment-variables.json
{
    "appid": {
        "__name": "APPID_CREDENTIALS",
        "__format": "json"
    },
    "cloudant": {
        "__name": "CLOUDANT_CREDENTIALS",
        "__format": "json"
    },
    "url": "APPLICATION_URL"
}

早速設定した資格情報を使ってsession storeを構成してみます。app.jsを以下のように変更します。

app.js
const CloudantStore = require('connect-cloudant-store')(session);
const Cloudant = require('@cloudant/cloudant');
const cloudant = Cloudant({
  url: config.get('cloudant.url'),
  plugins: {
    iamauth: {
      iamApiKey: config.get('cloudant.apikey')
    }
  }
});
const store = new CloudantStore({client: cloudant});
app.use(session({
  secret: '123456',
  resave: true,
  saveUninitialized: true,
  store
}));

CloudantStoreのパラメータではIAMベースの認証を行うオプションがないので、先にCloudantクライアントを作成してそれを渡すようにしました。次にsessionをちゃんと保持できているかの確認を容易に行うため、APIにカウンターをつけてみます。

routes/users.js
router.get('/user', function(req, res, next) {
  const count = (req.session.count || 0)+1;
  req.session.count = count;
  res.json({
    login: !!req.user,
    given_name: req.user?.given_name,
    count
  });
});

そのカウンターをUIで表示する部分も追加しておきます。

client/src/App.js
        <p>
          Hello {user.given_name || "Unknown User"}!
          Count: {user.count}
        </p>

これでUIをリロードすると、以下のようにCount: 1が表示され、リロードするたびに増えていくのがわかると思います。
スクリーンショット 2022-01-05 0.37.53.png

Cloudantの管理画面から中身を見るとちゃんとcount: 1が保持されているのがわかります。
スクリーンショット 2022-01-05 0.31.53.png
また、カウントを増やした状態で一度アプリケーションを再起動してもカウントが維持されていることがわかります。

ここまでで基本的な動作は確認できたので、sessionのTTLを60秒にセットしてexpireの挙動を確認します。

app.js
const store = new CloudantStore({
  client: cloudant,
  ttl: 60
});

これでアプリケーションを再起動すると、1分以内にリロードしているうちはログイン状態も保持されカウントもアップしていきますが、1分以上経ってからリロードするとログイン状態も解除され、カウントも1に戻ることがわかります。

IBM Cloud Code Engineでの動作確認

Cloudantをsession storeに使ったアプリケーションがCode Engine上で正しく動くかどうかを確認します。ttlを3600(1時間)にセットしてコードをGitHubにpushしておきます。

まずCloudantのcredentialsを前回のApp IDのcredentialsと同様、プロジェクトの「シークレット及びconfigmap」からシークレットとして保存しておきます。
スクリーンショット 2022-01-05 9.21.46.png
次にpushしたコードから新しいイメージをビルドしておく必要があるので、Code Engineのコンソールからプロジェクトを選択し、「イメージ・ビルド」から該当するビルドを選択し、「ビルドの実行依頼」をクリックしてしばらく待つと新しいイメージが作成されます。最後にアプリケーションの構成から「編集して新規リビジョンを作成」をクリックし、新しいイメージを使ったリビジョンを作成します。この時「環境変数」タブからCloudantのcredentialsを環境変数に取り込むように設定します。
スクリーンショット 2022-01-05 9.24.06.png
リビジョンを作成してしばらく待つとデプロイが完了し、アプリケーションが使えるようになります。トップページにアクセスしてカウントが表示されていること、またログインした状態にしてしばらく放置します。数分経つとCode Engineのインスタンスは自動的に停止されます。
スクリーンショット 2022-01-05 9.17.45.png
停止されたことが確認できたら、再度アプリケーションをリロードしてみます。この時はインスタンスが停止されているのでロードにしばらく時間がかかりますが、アプリケーションが起動してトップページが表示されると、ログイン状態やカウントが維持されているのがわかります。

注意点

IBM CloudantのLiteプランは、1秒当たりの読み書きの回数に制限があるので、プロダクションでの利用を検討する場合は、Standardプランや他のストアの利用を検討した方が良いです。

また、@cloudant/cloudantモジュールはdeprecatedなのでconnect-cloudant-store自体をプロダクションで使い続けるのはあまり得策ではないかもしれません。現状は後継であるclouding-node-sdkを使ったsession storeの実装はないようなので、もしプロダクションで使う場合は自分で実装するなどの代替手段を取る必要がありそうです。

まとめ

IBM Cloudantをsession storeとして使えることが確認できました。Liteプランなので一部制限はありますが、開発段階では問題なく利用できると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0