passport-google-oauth2 icon indicating copy to clipboard operation
passport-google-oauth2 copied to clipboard

TokenError: Code was already redeemed and TokenError: Bad Request

Open ghost opened this issue 8 years ago • 34 comments

I have a pretty basic passport setup as you can see below. Every once in a while I get two different errors. TokenError: Code was already redeemed and TokenError: Bad Request for reasons I cannot seem to find.

I've looked around a lot (1 week) for possible solutions but am yet to find one which works.

Do you see anything wrong with the current code?

app.get('/auth/google', redirect, passport.authenticate('google', { scope: ['profile', 'email'] }));

app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/' }),
  function(req, res) {
    res.redirect('/');
  }
);

Here are the two errors:

TokenError: Bad Request 
  at Strategy.OAuth2Strategy.parseErrorResponse (/app/node_modules/passport-oauth2/lib/strategy.js:320:12) 
  at Strategy.OAuth2Strategy._createOAuthError (/app/node_modules/passport-oauth2/lib/strategy.js:367:16) 
  at /app/node_modules/passport-oauth2/lib/strategy.js:166:45 
  at /app/node_modules/oauth/lib/oauth2.js:177:18 
  at passBackControl (/app/node_modules/oauth/lib/oauth2.js:123:9) 
  at IncomingMessage.<anonymous> (/app/node_modules/oauth/lib/oauth2.js:143:7) 
  at emitNone (events.js:85:20) 
  at IncomingMessage.emit (events.js:179:7) 
  at endReadableNT (_stream_readable.js:913:12) 
  at _combinedTickCallback (internal/process/next_tick.js:74:11) 
  at process._tickCallback (internal/process/next_tick.js:98:9)



TokenError: Code was already redeemed. 
      at Strategy.OAuth2Strategy.parseErrorResponse (/app/node_modules/passport-oauth2/lib/strategy.js:320:12) 
      at Strategy.OAuth2Strategy._createOAuthError (/app/node_modules/passport-oauth2/lib/strategy.js:367:16) 
      at /app/node_modules/passport-oauth2/lib/strategy.js:166:45 
      at /app/node_modules/oauth/lib/oauth2.js:177:18 
      at passBackControl (/app/node_modules/oauth/lib/oauth2.js:123:9) 
      at IncomingMessage.<anonymous> (/app/node_modules/oauth/lib/oauth2.js:143:7) 
      at emitNone (events.js:85:20) 
      at IncomingMessage.emit (events.js:179:7) 
      at endReadableNT (_stream_readable.js:913:12) 
      at _combinedTickCallback (internal/process/next_tick.js:74:11) 
      at process._tickCallback (internal/process/next_tick.js:98:9) 

ghost avatar Sep 23 '16 01:09 ghost

👍

ckelner avatar Jul 05 '17 06:07 ckelner

After a bit of digging, it looks like failureRedirect is ONLY used for strategy 'failures' and not 'errors', which is what gets thrown if a Token has already been used/redeemed.

This is a bit confusing, I agree.

It's almost as if passport needs an additional option for 'errorRedirect'

You can handle this outside of passport by implementing your own error handling. For example:

app.get('/auth/google/callback',
  passport.authenticate('google'), // complete the authenticate using the google strategy
  (err, req, res, next) => { // custom error handler to catch any errors, such as TokenError
    if (err.name === 'TokenError') {
     res.redirect('/auth/google'); // redirect them back to the login page
    } else {
     // Handle other errors here
    }
  },
  (req, res) => { // On success, redirect back to '/'
    res.redirect('/');
  }
);

njbraun avatar Aug 25 '17 20:08 njbraun

someone please give a solution to that problem i have tried almost everything on internet but that shit just fails to work in the deployment(only google cloud) even though it works fine on other cloud platform and even on localhost

prabhakarupadhyay avatar Feb 27 '18 22:02 prabhakarupadhyay

Still struggling with this too ...

thomasbromehead avatar Jun 12 '18 12:06 thomasbromehead

I am getting only first error: TokenError: Bad Request

I have no idea what to do.

suyash-purwar avatar Jul 09 '18 07:07 suyash-purwar

Try inspecting the TokenError (in my case the code property was helpful). If you're using express and errorHandler you can get some additional detail by manually logging the error:

  app.use(errorHandler({ log: errorNotification }));

  function errorNotification(err, str, req) {
    console.log('ERROR', err);
  }

This allowed me to see the code property (redirect_uri_mismatch) which helped me determine the actual issue.

ERROR! { TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (/home/ec2-user/environment/revtm/node_modules/passport-oauth2/lib/strategy.js:345:12) at Strategy.OAuth2Strategy._createOAuthError (/home/ec2-user/environment/revtm/node_modules/passport-oauth2/lib/strategy.js:394:16) at /home/ec2-user/environment/revtm/node_modules/passport-oauth2/lib/strategy.js:172:45 at /home/ec2-user/environment/revtm/node_modules/oauth/lib/oauth2.js:191:18 at passBackControl (/home/ec2-user/environment/revtm/node_modules/oauth/lib/oauth2.js:132:9) at IncomingMessage. (/home/ec2-user/environment/revtm/node_modules/oauth/lib/oauth2.js:157:7) at IncomingMessage.emit (events.js:187:15) at endReadableNT (_stream_readable.js:1081:12) at process._tickCallback (internal/process/next_tick.js:63:19) name: 'TokenError', message: 'Bad Request', code: 'redirect_uri_mismatch', uri: undefined, status: 500 }

dennyferra avatar Jul 17 '18 18:07 dennyferra

you have to specify the full url in the callbackURL section of the strategy: for example: when i'm running my code locally on localhost:3000 with code like this:

passport.use(new googleStrategy({

	clientID:keys.clientID,
	clientSecret:keys.clientSecret,
	callbackURL:'auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{

	console.log(accessToken);
	console.log(refreshToken);
	console.log(profile);
}
));

app.get('/auth',passport.authenticate('google',{

	scope:['profile','email']
}));

app.get('/auth/google/callback', 
  passport.authenticate('google'));

The above code will surely throw an error like token:Bad request. so you have pass the complete URl so the final code will be:

passport.use(new googleStrategy({

	clientID:keys.clientID,
	clientSecret:keys.clientSecret,
	callbackURL:'http://localhost:3000/auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{

	console.log(accessToken);
	console.log(refreshToken);
	console.log(profile);
}
));

app.get('/auth',passport.authenticate('google',{

	scope:['profile','email']
}));

app.get('/auth/google/callback', 
  passport.authenticate('google'));

akash5324 avatar Jul 28 '18 01:07 akash5324

akash5324, Thank you.

LuckyMadu avatar Aug 13 '18 13:08 LuckyMadu

i am wondering that why just this happen as i had used passport google for authentication.and i also make a call to drive api so that i am getting the drives data of users in my app easily and access token as well in my console but on the web page i am getting error as :: bad request or code is already redeemed

shubham2896yadav avatar Aug 29 '18 14:08 shubham2896yadav

when I console.log(profile) I can not get the user profile it shows me just [object object]? i am sorry for my bad english.

seif1000 avatar Sep 15 '18 18:09 seif1000

Hello.. Is there an answer in this problem ?

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (C:\Users\dc\Documents\cc\node_modules\passport-oauth2\lib\strategy.js:329:12) at Strategy.OAuth2Strategy._createOAuthError (C:\Users\dc\Documents\cc\node_modules\passport-oauth2\lib\strategy.js:376:16) at C:\Users\dc\Documents\cc\node_modules\passport-oauth2\lib\strategy.js:166:45 at C:\Users\dc\Documents\cc\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (C:\Users\dc\Documents\cointrade\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (C:\Users\dc\Documents\cc\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:187:15) at endReadableNT (_stream_readable.js:1086:12) at process._tickCallback (internal/process/next_tick.js:63:19)

rinzinsama avatar Sep 24 '18 09:09 rinzinsama

I'm having the same problem having already tried out every solution mentioned above. Keys are fine, dev and prod env on heroku are setup ok...

The call back url is also in full.

I suspect the problem is with the strategy but I can't finger it out. When I console log I can see the user profile but for the oddest reason I keep getting thrown to a Tokken error.

Here's my code:

passport.use(
  new OAuth2Strategy(
 {
 clientID: keys.googleClientID,
 clientSecret: keys.googleClientSecret,
 callbackURL: keys.googleCallBackUrl,
 proxy: true
 },
(accessToken, refreshToken, profile, done) => {
console.log(accessToken);     
console.log(refreshToken);     
console.log(profile);     
new User({ googleId: profile.id }).save();     
}
));
app.get("/auth/google/callback", passport.authenticate("google")),
app.get("/logout", (req, res) => {
req.logout();
res.redirect("/");
});

bildo17 avatar Nov 06 '18 18:11 bildo17

After reviewing the other passport strategy examples (GitHub), I think what is missing is the done callback in the passport callback, like this:

passport.use(
  new GoogleStrategy(
    {
      clientID: config.google.clientID,
      clientSecret: config.google.clientSecret,
      callbackURL: '/auth/google/redirect'
    },
    function(accessToken, refreshToken, profile, done) {
      new User({
        username: profile.username,
        providerId: profile.id,
        provider: 'Google'
      })
        .save()
        .then((user) => {
          console.log({ user });
          done(null, user); //callback to let passport know that we are done processing
        });
    }
  )
);

lmilliken avatar Nov 21 '18 02:11 lmilliken

4-39

https://github.com/cdavidd/emaily/blob/master/services/passport.js

i am having this issue, i dont know why, im trying to save in the database, and everithing is cool with that, but i dont know if is a google authenticator problem, here is mi code in my repo.

or I don't know if is this line in passport.js

new User({ googleId: profile.id }).save();

cdavidd avatar Jun 15 '19 02:06 cdavidd

Hello all,

I had the same issue, and it got fixed once I removed the absolute path from the callbackURL in passport setup

    passport.use(new Strategy({
        clientID: GOOGLE_CLIENT_ID,
        clientSecret: GOOGLE_CLIENT_SECRET,
        callbackURL: `/api/${API_VERSION}/auth/google/callback`,
        passReqToCallback: true
    }

instead of

 callbackURL: `http://localhost:4000/api/${API_VERSION}/auth/google/callback`

Hopefully this will help at least some of you

bogdanmartinescu avatar Aug 02 '19 21:08 bogdanmartinescu

passport.use( new GoogleStrategy({ clientID: "" clientSecret: "", callbackURL: 'http://localhost:5000/auth/google/callback', proxy: true, }, (accessToken, refressToken, profile, done) => { //your code stuff. }), )

dpk1391981 avatar Sep 20 '19 09:09 dpk1391981

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (/Users/sachi/Desktop/oauth-playlist/node_modules/passport-oauth2/lib/strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (/Users/sachi/Desktop/oauth-playlist/node_modules/passport-oauth2/lib/strategy.js:405:16) at /Users/sachi/Desktop/oauth-playlist/node_modules/passport-oauth2/lib/strategy.js:175:45 at /Users/sachi/Desktop/oauth-playlist/node_modules/oauth/lib/oauth2.js:191:18 at passBackControl (/Users/sachi/Desktop/oauth-playlist/node_modules/oauth/lib/oauth2.js:132:9) at IncomingMessage. (/Users/sachi/Desktop/oauth-playlist/node_modules/oauth/lib/oauth2.js:157:7) at emitNone (events.js:111:20) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1064:12) at _combinedTickCallback (internal/process/next_tick.js:138:11)

I get this error. I have already changed to callback URL as well

passport.use(
    new GoogleStrategy({
        // options for google strategy
        callbackURL:'http://127.0.0.1:3001/auth/google/redirect',
        clientID:keys.google.clientID,
        clientSecret:keys.google.clientSecret
    }, (accessToken,refreshToken,profile,done) => {
        // passport callback function
        console.log("passport callback function fired");
        console.log(profile);
    })
);

still I get the same error

sachuu96 avatar Sep 22 '19 20:09 sachuu96

I'm experiencing the same problem but it seems weird that some have removed the absolute path to the callback url and some have added it to solve the problem. i gt the error with a relative path and it works with the absolute one.

Isabanur avatar Nov 07 '19 09:11 Isabanur

I am also getting TokenError: Bad Request

vishwa3 avatar May 08 '20 09:05 vishwa3

it will work for you and check your correct callback url. new GoogleStrategy({ clientID: keys.googleClientId, clientSecret: keys.googeClientSecret, callbackURL: 'http://localhost:9000/auth/google/callback', proxy: true, })

dpk1391981 avatar May 08 '20 11:05 dpk1391981

For me the problem was with final req handler, res.redirect('#/after-auth'); was casing this error.

router.get('/google/callback',
    passport.authenticate('google', { failureRedirect: '/login' }),
    function (req, res) {
        res.redirect('#/after-auth');
    }
);

changing to res.redirect('/#/after-auth'); helped.

router.get('/google/callback',
    passport.authenticate('google', { failureRedirect: '/login' }),
    function (req, res) {
        res.redirect('/#/after-auth');
    }
);

nameeshgabru avatar Jun 06 '20 08:06 nameeshgabru

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:405:16) at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:175:45 at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:322:22) at endReadableNT (_stream_readable.js:1187:12) at processTicksAndRejections (internal/process/task_queues.js:84:21)

I am getting this same error, can someone please explain what to do. All my routes are correctly setup and the callback URI is also correct. I am struggling for a week , please help me out.

himalay12345 avatar Jun 08 '20 04:06 himalay12345

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:405:16) at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:175:45 at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:322:22) at endReadableNT (_stream_readable.js:1187:12) at processTicksAndRejections (internal/process/task_queues.js:84:21)

I am getting this same error, can someone please explain what to do. All my routes are correctly setup and the callback URI is also correct. I am struggling for a week , please help me out.

Resolved: error was in sending the callback user data if anyone get the same error feel free to ask

himalay12345 avatar Jun 08 '20 11:06 himalay12345

After a bit of digging, it looks like failureRedirect is ONLY used for strategy 'failures' and not 'errors', which is what gets thrown if a Token has already been used/redeemed.

This is a bit confusing, I agree.

It's almost as if passport needs an additional option for 'errorRedirect'

You can handle this outside of passport by implementing your own error handling. For example:

app.get('/auth/google/callback',
  passport.authenticate('google'), // complete the authenticate using the google strategy
  (err, req, res, next) => { // custom error handler to catch any errors, such as TokenError
    if (err.name === 'TokenError') {
     res.redirect('/auth/google'); // redirect them back to the login page
    } else {
     // Handle other errors here
    }
  },
  (req, res) => { // On success, redirect back to '/'
    res.redirect('/');
  }
);

Is there any reason there isn't an errorRedirect option for cases like this? Seems much cleaner than writing a custom handler.

botv avatar Jun 16 '20 16:06 botv

try adding these two lines in passport configuration

app.use(passport.initialize());
app.use(passport.session());

it worked for me

spsp008 avatar Jun 27 '20 20:06 spsp008

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:405:16) at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:175:45 at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:322:22) at endReadableNT (_stream_readable.js:1187:12) at processTicksAndRejections (internal/process/task_queues.js:84:21) I am getting this same error, can someone please explain what to do. All my routes are correctly setup and the callback URI is also correct. I am struggling for a week , please help me out.

Resolved: error was in sending the callback user data if anyone get the same error feel free to ask

Hey could you please tell how did you resolve this issue, I am also facing the same

Manthan-Asher avatar Jul 10 '20 15:07 Manthan-Asher

TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:405:16) at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\passport-oauth2\lib\strategy.js:175:45 at C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (C:\Users\himal\OneDrive\Desktop\Git\codeial\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:322:22) at endReadableNT (_stream_readable.js:1187:12) at processTicksAndRejections (internal/process/task_queues.js:84:21) I am getting this same error, can someone please explain what to do. All my routes are correctly setup and the callback URI is also correct. I am struggling for a week , please help me out.

Resolved: error was in sending the callback user data if anyone get the same error feel free to ask

Hey could you please tell how did you resolve this issue, I am also facing the same

send the whole code I will find it out.

himalay12345 avatar Jul 11 '20 06:07 himalay12345

Hopefully this will help at least some of you

thanks was really helpful

ibraheemmawwal avatar Jul 23 '20 00:07 ibraheemmawwal

Please help how to fix this TokenError: Bad Request at Strategy.OAuth2Strategy.parseErrorResponse (D:\Programming\pp\oauth-playlist-lesson-9\node_modules\passport-oauth2\lib\strategy.js:358:12) at Strategy.OAuth2Strategy._createOAuthError (D:\Programming\pp\oauth-playlist-lesson-9\node_modules\passport-oauth2\lib\strategy.js:405:16) at D:\Programming\pp\oauth-playlist-lesson-9\node_modules\passport-oauth2\lib\strategy.js:175:45 at D:\Programming\pp\oauth-playlist-lesson-9\node_modules\oauth\lib\oauth2.js:191:18 at passBackControl (D:\Programming\pp\oauth-playlist-lesson-9\node_modules\oauth\lib\oauth2.js:132:9) at IncomingMessage. (D:\Programming\pp\oauth-playlist-lesson-9\node_modules\oauth\lib\oauth2.js:157:7) at IncomingMessage.emit (events.js:322:22) at endReadableNT (_stream_readable.js:1187:12) at processTicksAndRejections (internal/process/task_queues.js:84:21)

noorashref avatar Oct 16 '20 10:10 noorashref

you have to specify the full url in the callbackURL section of the strategy: for example: when i'm running my code locally on localhost:3000 with code like this:

passport.use(new googleStrategy({

	clientID:keys.clientID,
	clientSecret:keys.clientSecret,
	callbackURL:'auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{

	console.log(accessToken);
	console.log(refreshToken);
	console.log(profile);
}
));

app.get('/auth',passport.authenticate('google',{

	scope:['profile','email']
}));

app.get('/auth/google/callback', 
  passport.authenticate('google'));

The above code will surely throw an error like token:Bad request. so you have pass the complete URl so the final code will be:

passport.use(new googleStrategy({

	clientID:keys.clientID,
	clientSecret:keys.clientSecret,
	callbackURL:'http://localhost:3000/auth/google/callback'
},(accessToken,refreshToken, profile,done)=>{

	console.log(accessToken);
	console.log(refreshToken);
	console.log(profile);
}
));

app.get('/auth',passport.authenticate('google',{

	scope:['profile','email']
}));

app.get('/auth/google/callback', 
  passport.authenticate('google'));

this work fine. callbackURL:'http://localhost:3000/auth/google/callback

allyjohn07 avatar Dec 20 '20 07:12 allyjohn07