認証付きAPIを作る前準備 - 自作サービスづくり8
今回もWeb開発に関する記事です。
前回はbotを使った出欠確認・更新機能の実装を行いました。
developer-bpeldi2oerkd8.hatenablog.com
しかし、作成したAPIには認証がありません。
このため、URLさえわかってしまえば、APIを無関係の方が叩けてしまいます。
これは問題であるため、APIに認証機能を付け、
ユーザーが許可したシステムからしかAPIを叩けないように変更します。
APIの認証方法
APIの認証について全く知らなかったため、調べてみました。
調べると、いくつか種類があります。
Basic認証やDigest認証、OAuthなど有名なものも多いですが、
今回はこちらのページにもあるように、
より一般的な手法であるJWT認証を取り入れることにしました。
JWTとは
JWTはJSON Web Tokenの略で、JSON形式で書かれたデータをBase64urlでエンコードした認証用のトークンです。
署名があるため、改ざん防止ができます。
詳しい説明はこちらのサイトが非常に参考になりました。
scgajge12.hatenablog.com
構成の考案
現在のAPI周りの構成は以下のようになっています。
ここに認証を付けます。
今回は jsonwebtoken というパッケージを使います。
このドキュメントを見ると、JWTを発行する jwt.sign() と、JWTを検証する jwt.verify() が必要なことがわかりました。
このため、まずJWTを発行する /api/v1/login にアクセスし、JWTを発行した後そのJWTを返し、
そのJWTをヘッダーに追加してAPIを利用するときに検証するという流れを考えました。
これを図にしたのが以下の図です。
ここで、JWTを発行する際に通常はユーザー名とパスワードを使うそうですが、
今回はSlack上のチャンネルが対応しているので、
チャンネルIDとそのチャンネルのトークンを利用することにしました。
チャンネルのトークンはSlackの連携設定時に発行するものとし、
セキュリティ上の問題が発生した際に再発行できるようにします。
Slackとの連携機能の実装の際のDBと機能の整理
Slackとの連携機能を実装するうえで、DBと機能の整理をします。
データベースは以下のような構成にします。
(sequelizeというORMを利用)
scheduleテーブル
const Schedule = loader.database.define( 'schedules', { scheduleId: { type: Sequelize.UUID, primaryKey: true, allowNull: false }, scheduleName: { type: Sequelize.STRING, allowNull: false }, description: { type: Sequelize.TEXT, allowNull: false }, createdBy: { type: Sequelize.INTEGER, allowNull: false }, updatedAt: { type: Sequelize.DATE, allowNull: false }, roomId: { type: Sequelize.STRING } }, { freezeTableName: true, timestamps: false, indexes: [ { fields: ['createdBy', 'roomId'] } ] } );
roomテーブル
const Room = loader.database.define( 'rooms', { roomId: { type: Sequelize.STRING, primaryKey: true, allowNull: true }, roomToken: { type: Sequelize.STRING, allowNull: true } }, { freezeTableName: true, timestamps: false } );
次に、追加する機能を整理します。
追加したい機能は以下の通りです。
- Slackとの連携がされていない場合、slackとの連携ボタンを表示
- Slackとの連携がされている場合、slackとの連携設定変更ボタンの表示
- チャンネルIDの登録とトークン発行機能
- slackとの連係解除機能
- チャンネルIDの変更機能
- トークンの再発行機能
これらの機能をまず実装していきます。
ページの関係で次回に続きます。