i want to put some paramter in authenticate method like this

onRequest: [fastify.authenticate('scope')]

but i dont know how can i implement that

this is my code

route

fastify.post(
    "/",
    {
      onRequest: [fastify.authenticate],
    },
    async (req, reply) => {
      sem.take(async () => {
        let _news = createNews(req.body);
        if (_news) await generate(_news);
        sem.leave();
      });
    }
  );

and this is my jwt class

import fjwt from "@fastify/jwt";
import buildGetJwks from "get-jwks";

export default function register(fastify) {
  const getJwks = buildGetJwks({
    providerDiscovery: false,
    jwksPath: ".well-known/openid-configuration/jwks",
  });

  fastify.register(fjwt, {
    decode: { complete: true },
    secret: (request, token) => {
      const {
        header: { kid, alg },
        payload: { iss },
      } = token;
      return getJwks.getPublicKey({ kid, domain: iss, alg });
    },
    formatUser: function (user) {
      return {
        scope: user.scope,
      };
    },
  });

  fastify.decorate("authenticate", async function (request, reply) {
    try {
      const token = await request.jwtDecode();
      console.log(token.payload.scope);
      await request.jwtVerify();
    } catch (err) {
      reply.send(err);
    }
  });
  
}

this is working now and validate accesstoken with my identity server but i want to authorization user

1

There are 1 answers

0
Manuel Spigolon On BEST ANSWER

This is a pure JavaScript question.

Let's break the code:

In the following code, fastify.authenticate returns a function that is a onRequest hook

fastify.post(
    "/",
    {
      onRequest: [fastify.authenticate],
    },
    async (req, reply) => { }
  );

Now, let's examine the fastify.authenticate getter. It has a value equal to the async function, so you may execute it, but the request and reply objects are not present.

  fastify.decorate("authenticate", async function (request, reply) {
    // ...
  });

But, if you change the authenticate decorator to a factory function:

  fastify.decorate("authenticate", function (scope) {

    return scopedHook;

    async function scopedHook (request, reply) {
      const token = await request.jwtDecode();
      if (!token.payload.scope.includes(scope)) {
        throw new Error("Unauthorized");
      }
      await request.jwtVerify();
    }
  });

Here:

  • the authenticate decorator is a sync function that returns a function
  • the returned function has the scope variable in its closure
  • the decorator must be used by executing it:
fastify.post(
    "/",
    {
      onRequest: [fastify.authenticate('my-scope')],
    },
    async (req, reply) => { }
  );