@fastify/jwt

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.

4 min read Level 2/5 #fastify#jwt#auth
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.

@fastify/session →