passport-jwt icon indicating copy to clipboard operation
passport-jwt copied to clipboard

failWithError option missing

Open tobikl1 opened this issue 4 years ago • 6 comments

I'd like to return a custom json response when authentication fails instead of the plain 'Unauthorized' Text response. In the local strategy for this we can provide a failWithError option to the strategy, which causes the error to be forwared to the express error handling middleware.

Can we provide something like this to this strategy as well? When token is expired, an invalid token was provided or any other error i would like to return a more specific error message.

I might throw an error in the validate callback. When providing 'ignoreExpiration' i could then check the payload.exp in there manually to throw a custom error, but this does not handle tokens invalid for some other reason.

it prevents me from returning json consistently in a rest api.

tobikl1 avatar Jul 31 '20 10:07 tobikl1

just subscribed. need that feature too

mod3x avatar Aug 03 '20 23:08 mod3x

I Agree!

yeasir01 avatar Sep 07 '20 17:09 yeasir01

Related: https://github.com/nestjs/passport/issues/394

vanhumbeecka avatar Sep 29 '20 14:09 vanhumbeecka

My pull request #224 makes passport-jwt respect this setting. Hopefully it gets merged soon.

emdemir avatar Feb 27 '21 21:02 emdemir

It works here. Example app:

const express = require('express')
const passport = require('passport')
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt')

const app = express()

passport.use(new JwtStrategy(
  { secretOrKey: 'secret', jwtFromRequest: ExtractJwt.fromUrlQueryParameter('token') },
  (payload, done) => {
    console.log('Verify callback hit')
    // Always fail authentication:
    done(null, false)
  }
))

app.get('/protected',
  passport.authenticate('jwt', { failWithError: true }),
  (req, res) => res.send('Authenticated')
)

app.use((err, req, res, next) => {
  res.send('Error middleware hit')
  console.error(err)
})

app.listen(3000)

Sending a request to http://localhost:3000/protected?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.dtxWM6MIcgoeMgH87tGvsNDY6cHWL6MGW4LeYvnm1JA results in response body of "Error middleware hit". Terminal:

Verify callback hit
AuthenticationError: Unauthorized
...

Same with a request to http://localhost:3000/protected?token=invalidtoken, except "Verify callback hit" isn't logged.

What you might be getting confused with is the fact that even when failWithError is used, Passport still sets the response status to 401 by default. See here.

Otherwise could you provide a reproduction of what you're experiencing and what you expect?

noinkling avatar Feb 03 '22 05:02 noinkling

@noinkling

this is for when the JWT is valid, if the JWT is invalid or expired then your callback won't be hit. The issue he created is he wants to be able to perform some sort of side effect whenever the JWT is invalid such as making a DB call or modifying the response, currently that isn't doable AFAIK.

Romstar avatar Jul 22 '23 18:07 Romstar