mikenicholson / passport-jwt

Passport authentication using JSON Web Tokens
MIT License
1.96k stars 213 forks source link

failWithError option missing #215

Open tobikl1 opened 4 years ago

tobikl1 commented 4 years ago

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 4 years ago

just subscribed. need that feature too

yeasir01 commented 4 years ago

I Agree!

vanhumbeecka commented 4 years ago

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

emdemir commented 3 years ago

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

noinkling commented 2 years ago

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?

Romstar commented 1 year ago

@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.