Backstageとは
なにかと話題にしていますBackstageですが、ご存知無い方のためにあらためて。
BackstageはCNCFのプロジェクトの1つで、拡張性の高い開発者ポータルのOSSです。機能拡張などはPluginを追加導入することで実現します。
BackstageのNew Backend System
数多くのPluginを導入することで機能を追加できるBackstageですが、すでに用意されているPluginを導入する際にも手間がかかるのが課題でした。そうした点を改善しようとするのがNew Backend Systemです。
New Backend Systemは導入が簡単・便利になるのですが、それと既存機能の拡張方法も変わりました。今回はその機能拡張方法の1つをご紹介したいと思います。
認証機能の拡張方法
BackstageのAPIはデフォルトでは認証確認がなく、誰でもアクセスできるようになっています。こうした点を改善し、原則すべてのAPIアクセスで認証確認を行うようにするPluginを以前ご紹介しました。
今回はこの機能をNew Backend System対応にしていきます。
旧Backend Systemでの対応方法
旧Backend Systemでは、backend packageのmainでルーティング情報を登録していました。ここでExpressJSのMiddlewareとして登録すればOKでした。
// packages/backend/src/index.ts from a create-app deployment import { createAuthMiddleware, setCookieService } from '@platt/plugin-http-router-backend-module-authorization'; import cookieParser from 'cookie-parser'; // ... async function main() { // ... const authMiddleware = await createAuthMiddleware(config, appEnv); const apiRouter = Router(); apiRouter.use(cookieParser()); // The auth route must be publicly available as it is used during login apiRouter.use('/auth', await auth(authEnv)); // Add a simple endpoint to be used when setting a token cookie apiRouter.use('/cookie', authMiddleware, setCookieService); // Only authenticated requests are allowed to the routes below apiRouter.use('/catalog', authMiddleware, await catalog(catalogEnv)); apiRouter.use('/techdocs', authMiddleware, await techdocs(techdocsEnv)); apiRouter.use('/proxy', authMiddleware, await proxy(proxyEnv)); apiRouter.use(authMiddleware, notFoundHandler()); // ... }
新Backend Systemでの対応
新Backend Systemではルーティング情報なども隠蔽されており、利用者は意識する必要はなくなりました。 このため、認証などの機能を付加するためには旧Backend Systemとは異なる方法で行う必要があります。
新Backend Systemでは、各種のサービスをServiceFactoryとして用意し、その中で指定するようになります。デフォルトのServiceFactoryは @backstage/backend-defaults パッケージの中で指定されています。
export const defaultServiceFactories = [ cacheServiceFactory(), rootConfigServiceFactory(), databaseServiceFactory(), discoveryServiceFactory(), httpRouterServiceFactory(), identityServiceFactory(), lifecycleServiceFactory(), loggerServiceFactory(), permissionsServiceFactory(), rootHttpRouterServiceFactory(), rootLifecycleServiceFactory(), rootLoggerServiceFactory(), schedulerServiceFactory(), tokenManagerServiceFactory(), urlReaderServiceFactory(), ];
ルーティング情報は rootHttpRouterServiceFactory
で指定されており、ここを上書きすることで認証機能を組み込みます。
イメージとしては以下のようになります(参考コード)。
import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; import cookieParser from 'cookie-parser'; import { authMiddlewareFactory } from './middlewares'; export default rootHttpRouterServiceFactory ({ configure: ({ app, config, logger, middleware, routes }) => { app.use(middleware.helmet()); app.use(middleware.cors()); app.use(middleware.compression()); app.use(cookieParser()); app.use(middleware.logging()); app.use(authMiddlewareFactory({ config, logger })); // Simple handler to set auth cookie for user app.use('/api/cookie', (_, res) => { res.status(200).send(); }); app.use(routes); app.use(middleware.notFound()); app.use(middleware.error()); }, });
これを以下のように組み込めばOKです。
const backend = createBackend(); backend.add(import('./上記モジュール'));
Pluginを利用する側は簡単になったのですが、それを拡張するためにはBackstageの中を理解していかないといけない、そんな仕組みになってきています。
便利な認証Plugin
今回ご紹介した認証機能はPluginとして簡単にご利用いただけるようになっています。 以前は認証確認Pluginは旧Backend Systemだけの対応でしたが、このたび新Backend Systemにも対応いたしました。 こちらを利用することで、面倒なコーディングを追加することなくAPIに認証確認機能を付加いただけるようになっています。
ぜひご活用ください。