Create an auth.js middleware

2.6k views Asked by At

I have created an auth.js middleware with fastify and prisma but I don't know how to insert it in my route. Here are some examples

const jwt = require("jsonwebtoken");
require("dotenv").config();

module.exports = (request, reply) => {
  try {
    const token = request.headers.authorization.split(" ")[1];
    const decodedToken = jwt.verify(token, process.env.SECRET_TOKEN);
    request.token = decodedToken;
  } catch (error) {
    reply.status(401).send({
      message: "Vous êtes pas authentifié",
    });
  }
};
const profilCtrl = require("../../controller/user");

const auth = require("../../middleware/auth");
async function routes(fastify) {
  fastify.get("/profil/:id", profilCtrl.profile);
}

module.exports = routes;
2

There are 2 answers

0
Glenn On

You can add your auth function as a preHandler hook like this:

fastify.addHook('preHandler', (request, reply, done) => {
  // some code
  done()
})

or like this:

fastify.route({
  method: 'GET',
  url: '/profil/:id',
  preHandler: fastify.auth([fastify.yourMiddleware]),
  handler: (req, reply) => { ... }
})

Looking at your code I'm not totally clear on if it represents multiple files or what exactly is going on. You might want to break it up into separate blocks of code with file names to clarify your question.

0
Towerss On

For anyone else working with JWT authentication in Fastify, fastify has a great plugin to support it:

For authentication with JWT you can create a plugin to decorate the fastify instance with authenticate like this:

import fastifyPlugin from 'fastify-plugin';
import fastifyJwt, { FastifyJWTOptions } from '@fastify/jwt';
import { FastifyRequest, FastifyReply } from 'fastify';

export default fastifyPlugin<FastifyJWTOptions>(async (fastify) => {
    fastify.register(fastifyJwt, {
        secret: '',
        decode: { complete: true },
        sign: { algorithm: 'RS256', expiresIn: '1h' },
        decoratorName: 'jwtUser',
    });

    fastify.decorate(
        'authenticate',
        async (request: FastifyRequest, reply: FastifyReply) => {
            try {
                await request.jwtVerify();
            } catch (error) {
                throw fastify.httpErrors.unauthorized();
            }
        }
    );
});

Then, you can use it from any route you would like to authenticate the user like this:

import { FastifyPluginAsync } from 'fastify';

const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
    fastify.get(
        '/',
        {
            schema: {},
            onRequest: [fastify.authenticate],
        },
        (request, reply) => {
            return reply.code(200).send('Welcome!')
        }
    );
};

export default root;

Authentication is better done earlier on the lifecycle, like onRequest, to prevent DOS attacks when the body of the request is processed.

If you are using Typescript, you might need to extend Fastify types. You can do it like this:

import 'fastify';
import { FastifyRequest, FastifyReply } from 'fastify';
declare module 'fastify' {

    /**
     * Type function to extend FastifyInstance to work with hook authentication
     * onRequest: [fastify.authenticate] defined at src\plugins\jwtVerification.ts
     */
    type Authenticate = (
        request: FastifyRequest,
        reply: FastifyReply
    ) => Promise<void>;

    /** Apply the extension */
    interface FastifyInstance {
        authenticate: Authenticate;
    }
}