メインコンテンツまでスキップ

認証

備考

フックとコントローラーとの間でデータを共有するには AdditionalRequest を使用します。

cd server
npm install @fastify/jwt

プラグインの登録

$/service/app.ts
import Fastify, { FastifyServerFactory } from 'fastify';
import fastifyJwt from '@fastify/jwt';
import { API_JWT_SECRET, API_BASE_PATH } from '$/service/envValues';
import server from './$server';

export const init = (serverFactory?: FastifyServerFactory) => {
const app = Fastify({ serverFactory });
app.register(fastifyJwt, { secret: API_JWT_SECRET });
server(app, { basePath: API_BASE_PATH });
return app;
};

トークンの発行

$/api/token/controller.ts
import { defineController } from './$relay';
import { validateUser } from '$/service/user';

export default defineController((fastify) => ({
post: ({ body }) =>
validateUser(body.id, body.pass)
? { status: 201, body: { token: fastify.jwt.sign({ id: body.id }) } }
: { status: 401 },
}));

トークンの検証

@fastify/jwtFastifyRequest を拡張していますが、これはコントローラーに反映されないので、参照するには自分で用意する必要があります。

プラグインによる型の拡張の反映

$/api/user/hooks.ts
import { defineHooks } from './$relay';

export type AdditionalRequest = {
user: {
id: string;
};
};

export default defineHooks(() => ({
onRequest: (request, reply) => request.jwtVerify().catch((err) => reply.send(err)),
}));
$/api/user/controller.ts
import { defineController } from './$relay';
import { getUserNameById } from '$/service/user';

export default defineController(() => ({
get: async ({ user }) => ({ status: 200, body: await getUserNameById(user.id) }),
// ^^^^ extended by AdditionalRequest
}));