mikenicholson / passport-jwt

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

No auth token #130

Closed heinhoang closed 5 years ago

heinhoang commented 7 years ago

Using: "jsonwebtoken": "^7.4.3", "passport": "^0.4.0", "passport-jwt": "^3.0.0",

jwt config

const passport = require('passport');
const { Strategy: JWTStrategy, ExtractJwt } = require('passport-jwt');

const jwtOpts = {
  // Telling Passport to check authorization headers for JWT
  jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Authorization'),
  // Telling Passport where to find the secret
  secretOrKey: process.env.JWT_SECRET || 'abc',
};

passport.use(new JWTStrategy(jwtOpts, (payload, done) => {
  console.log('err');
  User.findOne({ id: payload.sub }, (err, user) => {
    if (err) {
      return done(err, false, { message: 'meet error', error: err });
    }
    if (!user) {
      return done(null, false, { message: 'there\'s no user associated with this token' });
    }
    return done(null, user);
  });
}));

generate token like this

const jwt = require('jsonwebtoken');
myjon.token = `JWT ${jwt.sign({ _id }, process.env.JWT_SECRET )}`;

In Postman

Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5c....

and get error:

"code": "E_UNAUTHORIZED",
 "message": "No auth token",
mikenicholson commented 7 years ago

This line:

 jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Authorization');

would require to use the header

Authorization: Authorization eyJhbGciOiJIUzI1NiIsInR5c....

The issues is that you're looking for an Authorization header with the scheme of 'Authorization'. If you want the scheme to be 'JWT' you should use

 jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT');

Note that the scheme comparison is case-insensitive so 'JWT' and 'jwt' are equivalent.

good-idea commented 7 years ago

This solution worked for me but coming with a different problem. I was using ExtractJwt.fromAuthHeaderAsBearerToken()

And a header that looked like: authorization: 'JWT eyJHGc...'

This was giving me the error "No auth token".

Switching to ExtractJwt.fromAuthHeaderWithScheme('JWT') worked. Or, while using ExtractJwt.fromAuthHeaderAsBearerToken(), changing the header token string to be authorization: 'Bearer eyJHGc...' also worked.

So, I've learned something about schemas.

I believe that I had set things up with ExtractJwt.fromAuthHeaderAsBearerToken() because I was using an older project, which used ExtractJwt.fromAuthHeader() (a 2.0 method), as a template. Either a StackOverflow question or a tutorial mentioned ExtractJwt.fromAuthHeaderAsBearerToken() as a replacement.

Regardless: I've figured it out now, but it was a pain to debug since passport is (understandably so) pretty black-box when it comes to errors - I was just getting a 401.

Hopefully this saves someone else some headache!

kasvith commented 6 years ago

authorization: 'Bearer eyJHGc...' worked for me too

mikenicholson commented 5 years ago

Closing.