passport icon indicating copy to clipboard operation
passport copied to clipboard

Always unauthorized!

Open jovi-tsx opened this issue 3 years ago • 6 comments
trafficstars

Why is my routes always getting unauthorized?

This is where i'm setting my JWT Token:

authRouter.get('/callback', passport.authenticate('google', {
  failureRedirect: '/',
  session: false
}), (req, res) => {
  const user = {
    display_name: req.user.displayName,
    email: req.user._json.email,
    provider: req.user.provider
  }

  const token = generateJWT(user)

  res.cookie('x-auth-cookie', token)
  res.redirect('/')
})

This is how i'm generating the token (gerateJWT):

const generateJWT = (payload) => {
  return jwt.sign({
    ...payload,
    expiresIn: 2 * 60 * 60
  }, secretOrKey);
}

This is my JWT Strategy:

passport.use(new JwtStrategy(
  {
    jwtFromRequest: ExtractJwt.fromHeader('x-auth-cookie'),
    secretOrKey,
  },
  (payload, done) => {
    done(null, payload)
  },
))

In my route i'm just using:

passport.authenticate('jwt', { session: false })

jovi-tsx avatar Apr 23 '22 01:04 jovi-tsx

Have you used debugging tools to verify that cookies are getting set and transmitted in HTTP requests as expected? Any details as to network traffic would be helpful.

jaredhanson avatar Apr 23 '22 01:04 jaredhanson

Have you used debugging tools to verify that cookies are getting set and transmitted in HTTP requests as expected? Any details as to network traffic would be helpful.

My request headers, i don't know if this can help:

GET /secret HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: max-age=0
Connection: keep-alive
Cookie: x-auth-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkaXNwbGF5X25hbWUiOiJKb8OjbyBab3J6ZXR0aSIsImVtYWlsIjoiam9hby56b3J6ZXR0aUBnbWFpbC5jb20iLCJwcm92aWRlciI6Imdvb2dsZSIsImV4cGlyZXNJbiI6IjFkIiwiaWF0IjoxNjUwNjc3MDU4fQ.voZWZkxNSG7wVp9gbTnuepq6wKnrcbgVUHm6YnevB7U
Host: localhost:4000
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Sec-GPC: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36

Also my "expires/max-age" is written: "Session"

jovi-tsx avatar Apr 23 '22 01:04 jovi-tsx

I'm not familiar with the implementation of the jwt strategy, but your JWT has an expiresIn, where the standard mandates an exp claim. This may be causing issues.

jaredhanson avatar Apr 23 '22 01:04 jaredhanson

I'm not familiar with the implementation of the jwt strategy, but your JWT has an expiresIn, where the standard mandates an exp claim. This may be causing issues.

I tried removing it, still the same... In JWT Strategy the payload and done isn't running at all, i tried to console.log there and nothing was returned, but I can't find a problem with my headers or why ExtractJwt.fromHeader() isn't working

jovi-tsx avatar Apr 23 '22 01:04 jovi-tsx

I think the problem is in how you are generating the JWT.

return jwt.sign({
    ...payload,
    expiresIn: 2 * 60 * 60
  }, secretOrKey);

Expires in should be an option, not part of the payload. Something like:

return jwt.sign({
   ...payload
 }, secretOrKey, { expiresIn: 2 * 60 * 60 });

jaredhanson avatar Apr 23 '22 01:04 jaredhanson

I think the problem is in how you are generating the JWT.

return jwt.sign({
    ...payload,
    expiresIn: 2 * 60 * 60
  }, secretOrKey);

Expires in should be an option, not part of the payload. Something like:

return jwt.sign({
   ...payload
 }, secretOrKey, { expiresIn: 2 * 60 * 60 });

You're right about that, but even with this I'm still having the problem :. It seems like it isn't reading my header at all

jovi-tsx avatar Apr 23 '22 02:04 jovi-tsx

you can try to use ExtractJwt.fromExtractors([cookieExtractor]) instead of fromHeaders.

then you will create a function:

function cookieExtractor(req: Request): string | null {
    let jwt = null;
    if (req && req.headers && req.headers.cookie) {
      const [key, value] = req.headers.cookie.split('=');
      jwt = value;
    }
    return jwt;
  }

I realised that the cookie will be a string of key value pair, so you might need to split the key and value(jwt).

kevzzsk avatar Mar 29 '23 02:03 kevzzsk