Strategy.OAuth2Strategy.parseErrorResponse 出错 - NodeJS passport google oauth2.0

7

我正在尝试在Node.js中使用passport和google passport-google-oauth20嵌入谷歌身份验证。问题是当谷歌回调路由打开时,我会收到以下信息:

Error
at Strategy.OAuth2Strategy.parseErrorResponse (E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:329:12)
at Strategy.OAuth2Strategy._createOAuthError (E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:376:16)
at E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js:166:45
at E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:191:18
at passBackControl (E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:132:9)
at IncomingMessage.<anonymous> (E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js:157:7)
at emitNone (events.js:110:20)
at IncomingMessage.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1059:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)

我(或多或少)遵循这个教程。 以下是我的代码: 路由(以“/auth”开头)
'use strict'

const passport = require('passport')
const router = require('express').Router()

router.get(
  '/google',
  (req, res, next) => {
    if (req.query.return) {
      req.session.oauth2return = req.query.return
    }
    next()
  },
  passport.authenticate('google', { scope: ['email', 'profile'] })
)

router.get(
  '/google/callback',
  passport.authenticate('google'),
  (req, res) => {
    const redirect = req.session.oauth2return || '/';
    delete req.session.oauth2return;
    res.redirect(redirect);
  }
);

module.exports = router

有一个护照配置:

'use strict'
const passport = require('passport')
const keys = require('./keys')
const GoogleStrategy = require('passport-google-oauth20').Strategy
const userController = require('../controllers/user-controller')

const passportConfig = {
  clientID: keys.google.clientId,
  clientSecret: keys.google.clientSecret,
  callbackURL: 'auth/google/callback',
  accessType: 'offline'
}

passport.use(new GoogleStrategy(passportConfig,
  (accessToken, refreshToken, profile, done) => {
  console.log(accessToken, refreshToken, profile, done)
  userController.getUserByExternalId('google', profile.id)
  .then(user => {
    if (!user) {
      userController.createUser(profile, 'google')
      .then(user => {
        return done(null, user)
      })
      .catch(err => {
        return done(err)
      })
    }
    return done(null, user)
  })
  .catch(err => {
    return done(err)
  })
}))

passport.serializeUser((user, cb) => {
  cb(null, user)
})
passport.deserializeUser((obj, cb) => {
  cb(null, obj)
})

正如您所看到的,我在新的GoogleStrategy第二个参数函数中添加了console.log,但它从未触发。

//编辑 我注意到,我使用的是require('passport-google-oauth20')而不是分配require('passport-google-oauth20').Strategy。 但是修复它并没有改变任何东西,仍然是相同的错误。 我可以补充的问题是,在我的主要失败中,我调用

// sets passport config
require('./config/jwt-auth')
require('./config/google-auth')

// initialize passport
app.use(passport.initialize())

所以我不认为里面有任何问题。

6个回答

9

你需要在策略的callbackURL部分指定完整的url,例如:如果在localhost:3000上本地运行代码,则应像这样编写代码:

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'));

上述代码肯定会抛出TokenError: Bad request异常。您需要传递完整的URL才能得到以下示例中显示的最终代码:
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'));

2

您可以通过在node模块下的Oauth和Strategy中放置一些console.log来获得帮助,特别是在日志中获取错误的那一行。

E:\Programowanie\NodeJS\Hydronide\node_modules\passport-oauth2\lib\strategy.js
E:\Programowanie\NodeJS\Hydronide\node_modules\oauth\lib\oauth2.js

这将帮助您找到解析错误的根本原因。似乎请求/响应数据存在问题。


0
passport.use(new GoogleStrategy({
        clientID: process.env.CLIENT_ID,
        clientSecret: process.env.CLIENT_SECRET,
        callbackURL: "http://localhost:3000/auth/google/home"
    },
    function(accessToken, refreshToken, profile, cb) {
        console.log(profile);
        User.findOrCreate({ username: profile.displayName, googleId: profile.id }, 
    function (err, user) {
        return cb(err, user);
    });
}));

1
如果你仔细看,你会意识到你写的代码和作者是一样的。在提供任何解决方案之前,请密切关注错误信息。 - fatiu

0
在 passport.js 中,您需要将 callbackURL 从 'auth/google/callback' 更改为 '/auth/google/callback'。不要忘记在 auth 前面添加 '/'。

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);
}
));


0
const express = require('express');
const router = express.Router();
const { User } = require('../models/user.model');
const jwt = require('jsonwebtoken');
const config = require('../config/config.json');
const role = require('../lib/role');


const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;

router.use(passport.initialize());

passport.serializeUser((user, cb) => {
  cb(null, user);
});


passport.deserializeUser((obj, cb) => {
  cb(null, obj);
});


passport.use(new GoogleStrategy({
  clientID: "sssssssssssssssssssssssssss",
  clientSecret: "Vsssssssssssssss",
  callbackURL: "http://localhost:4000/api/auth/google/callback"
},

  (request, accessToken, refreshToken, profile, cb) => {

    User.findOne({ email: profile.emails[0].value }, (err, user) => {
      if (err) {
        cb(err); // handle errors!
      }
      if (!err && user !== null) {
        cb(err, user);
      }
      else {

        user = new User({
          googleId: profile.id,
          email: profile.emails[0].value,
          firstname: profile.name.givenName,
          lastname: profile.name.familyName,
          role: role.Client,
          isActive: true,
          isGain: false,
        });

        user.save((err) => {
          if (err) {
            cb(err); // handle errors!
          } else {
            cb(null, user);
          }
        });
      }
    });
  }
));



router.get('/', passport.authenticate('google', { session: false, scope: ['profile', 'email'] }));

// callback
router.get('/callback', passport.authenticate('google', { failureRedirect: '/failed' }),
  (req, res) => {
    const token = jwt.sign({ userId: req.user._id, email: req.user.email, role: req.user.role }, config.secret_key, { expiresIn: '10 h' })
    res.status(200).json({ success: true, token, expireIn: `${new Date().getTime() + 120000}` })
  }
);


//failed auth google 
router.get('/failed', async (req, res) => { res.status(404).send('erreur authentification') })





module.exports = router; 

0

我通过检查这条路线解决了这个问题。

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

我试图为新用户做一些事情,为此我尝试从数据库中获取用户,如果成功获取,我将执行该操作,否则只需重定向到其他地方,但我遇到的问题是,您可以通过控制台日志检查此路由。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接