mikenicholson/passport-jwt

failWithError option missing

tobikl1 opened this issue ยท 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.

mod3x commented

just subscribed. need that feature too

I Agree!

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

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?