5

I have already implemented the jwt and it works correctly but when creating a middleware that verifies that the token is still active and that it is valid, if the token has already expired, you must create a new one in case you can not create a new one, return a 404 error with a message, So far I have only been able to obtain the token and decode it, I need to be able to verify it and return an error response or let it continue.

this is my middleware code code:

import { JwtService } from '@nestjs/jwt';
import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class JwtMiddleware implements NestMiddleware {
    valid = null;
    decode = null;
    cleanToken = null;

    constructor(private readonly jwtServ: JwtService) {}

    use(req: Request, res: Response, next: Function) {
        const token = req.headers['authorization'];
        try {
            this.cleanToken = token.replace('Bearer','').trim();
            this.decode = this.jwtServ.decode(this.cleanToken);            
        } catch (error) {
            // console.log(error);
        }

        try {
            this.valid = this.jwtServ.verify(this.cleanToken);
        } catch (error) {
            console.log(error.name);
            console.log(error.message);
            console.log(error.expiredAt);
        }

        next();
    }
}

up to here I could only print in console the error of verifying jwt but it is not the correct way to do it besides that I can not return a valid answer to the client

console print:

  • TokenExpiredError
  • jwt expired
  • 2019-03-27T00:18:56.000Z

I searched the jwt documentation to see how to validate the token and found it: https://github.com/auth0/node-jsonwebtoken

// verify a token symmetric
jwt.verify(token, 'shhhhh', function(err, decoded) {
  console.log(decoded.foo) // bar
});

but in nestjs it does not work that way. The function "function (err, decoded)" can not be implemented like this, so it marks me errors so I had to put it in a trycatch

I also tried this:

this.jwtServ.verify(token,(err, decoded) => {
        if (err) {
            return res.status(401).json({
                ok: false,
                message: 'Invalid Token',
                errors: err
            });
        }

        req.user = decoded.user;

        next();
    });

in the nestjs documentation he says:

The Nest middleware, by default, are equal to express middleware. Here's a great list of the middleware capabilities copied from the official express documentation

https://docs.nestjs.com/middleware

I've already tried this and it does not work

return res.status(401).json({
                ok: false,
                message: 'Invalid Token',
                errors: err
            });

Any help is welcome, thanks!

Joshue
  • 316
  • 1
  • 2
  • 8

3 Answers3

3

My solution this:

try {
  const validated = jwt.verify(token, {publicKey: myPublicKey})
  return validated
} catch(error) {
 // here comes if token invalid or expired 
}
Ari Waisberg
  • 1,186
  • 1
  • 12
  • 23
1

try this.. use 'jsonwebtoken' package

import * as jwt from 'jsonwebtoken';
jwt.verify(token, 'shhhhh', function(err, decoded){
 console.log(decoded.foo) // bar
});
0

At present, through your description, I think your main problem is that you want to implement jwt authentication and interrupt the request in the middleware and return the expected return value, you can refer to my example.

// jwt.middleware.ts

import { Injectable, NestMiddleware } from '@nestjs/common'
import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'

@Injectable()
export class JwtMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    if (!req.headers.authorization) {
      res.writeHead(401, { 'content-type': 'application/json' })
      res.write(JSON.stringify({
        msg: 'Authorization is required',
      }))
      res.end()
    } else {
      const token = req.headers.authorization.replace('Bearer','').trim()

      const validated = jwt.verify(token,  'secret_key')

      // Other requests using this middleware can get the parsed value in the 
      // parameter, you can also analyze the parsed value and return res as 
      // above for those that do not match
      req.body._validated = validated
    }
    next()
  }
}

As above, you can indicate the completion of middleware execution by executing the next function, and the processed content will be passed to the next layer, or you can call res.end to interrupt the request and describe the content of res.

export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(JwtMiddleware).exclude('api/users/login').forRoutes('api')
  }
}

Refer to:

Dong
  • 41
  • 5