Issue verifying token via query param using FastifyJWT: TypeError - request.jwtVerify is not a function

84 views Asked by At

The issue at hand revolves around the utilization of FastifyJWT for token verification in a Fastify application. Specifically, when attempting to perform the verification process on a token received via a query parameter in a GET request, the function request.jwtVerify(token) is producing the error "TypeError: request.jwtVerify is not a function".

The aim is to successfully extract and verify the token received through the URL query parameter in order to confirm a user's email address. The token is generated and sent via an email confirmation link, and upon receiving a GET request with this token, the intention is to validate it using FastifyJWT.

This workflow involves:

  • Generating the token for email confirmation.
  • Sending the token via a URL query parameter in an email confirmation link.
    const emailToken = await reply.jwtSign({}, {
      sub: email,
      expiresIn: '7d'
    });

    const messageData = {
      from: '[email protected]',
      to: '[email protected]',
      subject: 'Verificação de E-mail',
      text: `Clique neste link para verificar seu e-mail: ${env.APP_URL}/users/verify/email?token=${emailToken}`,
      html: `<p>Clique neste <a href="${env.APP_URL}/users/verify/email?token=${emailToken}">link</a> para verificar seu e-mail.</p>`
    }

    // Envio do e-mail de verificação
    const resMG = await mgClient.messages.create(env.MAILGUN_DOMAIN, messageData);

    console.log('Email enviado com sucesso: ', resMG)
  • Receiving a GET request with the token and attempting to verify it using FastifyJWT's request.jwtVerify() function.
import { makeVerifyUserEmailUseCase } from "@/application/factories/user/make-verify-user-email-use-case"
import { FastifyReply, FastifyRequest } from "fastify"
import { z } from "zod"

export default async function verifyUserEmail(request: FastifyRequest, reply: FastifyReply) {
  const verifyUserEmailQuerySchema = z.object({
    token: z.string(),
  })

  const { token } = verifyUserEmailQuerySchema.parse(request.query)
  console.log('TOKEN after parse: ', token)

  try {
    const decodedToken = request.jwtVerify({ token } as any, (error, decodedToken) => {
      if (error) {
        console.log('ERROR!')
        console.error(error)
        return reply.status(401).send('Erro na verificação do token')
      }
      return decodedToken
    })

    console.log('DECODED TOKEN: ', decodedToken)

    const emailToken = (decodedToken as any).sub.email
    console.log(emailToken)
    if ((decodedToken as any) && (decodedToken as any).sub?.email) {
      const verifyUserEmailUseCase = makeVerifyUserEmailUseCase()
      await verifyUserEmailUseCase.execute(emailToken)

      return reply.status(200).send({ message: 'E-mail verificado com sucesso!' })
    }
  } catch (error) {
    console.error(error)
  }

}

However, the code is encountering an issue with the request.jwtVerify() function, which seems to be unavailable or improperly utilized, resulting in the mentioned error.

The goal is to gain insights into why this error is occurring and how to rectify it, enabling successful token verification using FastifyJWT.

In attempting to resolve the issue, I first ensured that the @fastify/jwt plugin was correctly installed and configured within the application. The plugin setup appears to be in place:

import fastifyJwt from '@fastify/jwt'

app.register(fastifyJwt, {
  secret: env.JWT_SECRET,
  cookie: {
    cookieName: 'refreshToken',
    signed: false,
  },
  sign: {
    expiresIn: '10m',
  },
})

Any doubts are welcome, in case you need further information, I'm open to providing it. Thank you in advance for any assistance.

1

There are 1 answers

1
Howard Medeiros On

Try:

import { makeVerifyUserEmailUseCase } from "@/application/factories/user/make-verify-user-email-use-case";
import { FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";

export default async function verifyUserEmail(request: FastifyRequest, reply: FastifyReply) {
  const verifyUserEmailQuerySchema = z.object({
    token: z.string(),
  });

  try {
    const { token } = verifyUserEmailQuerySchema.parse(request.query) as { token: string };
    console.log('TOKEN after parse: ', token);

    const decodedToken = await request.jwtVerify({ token });

    console.log('DECODED TOKEN: ', decodedToken);

    const emailToken = decodedToken.sub.email;
    console.log(emailToken);

    if (decodedToken && decodedToken.sub?.email) {
      const verifyUserEmailUseCase = makeVerifyUserEmailUseCase();
      await verifyUserEmailUseCase.execute(emailToken);

      return reply.status(200).send({ message: 'E-mail verificado com sucesso!' });
    }
  } catch (error) {
    console.error(error);
    return reply.status(401).send('Erro na verificação do token');
  }
}