Issue & Verify JWTs With One Plugin
@fastify/jwt
The @fastify/jwt plugin provides app.jwt.sign and verify methods plus a jwtVerify helper on requests for protecting routes.
What you'll learn
- Install @fastify/jwt
- Register with a secret or key pair
- Use jwtVerify in a preHandler to gate routes
JWTs are signed JSON tokens. They are stateless — the server does not need to look up a session for each request. @fastify/jwt wraps jsonwebtoken and adds Fastify-shaped helpers.
Install & Register
npm install @fastify/jwt import jwt from '@fastify/jwt'
await app.register(jwt, {
secret: app.config.JWT_SECRET,
sign: { expiresIn: '1h' },
}) For production, prefer asymmetric keys ({ private, public }) so verifiers do not need the signing secret.
Issuing a Token
app.post('/login', async (req, reply) => {
// ... validate credentials ...
const token = await reply.jwtSign({ sub: 'user-123', role: 'admin' })
return { token }
}) Protecting Routes
The plugin adds request.jwtVerify() — use it from a preHandler.
const auth = async (req: FastifyRequest, reply: FastifyReply) => {
try {
await req.jwtVerify()
} catch {
reply.code(401).send({ error: 'unauthorized' })
}
}
app.get('/me', { preHandler: [auth] }, async (req) => {
return { user: req.user }
}) After jwtVerify, the decoded payload lands on request.user. Declare its shape via TypeScript module augmentation for type-safe access.