如何validation服务器端的js节点的谷歌身份validation令牌?

我的前端应用程序使用Gmail帐户进行身份validation

validation成功后,我检索id_token ,并将其作为授权标头发送为承载令牌

例如http:// localhost:4000 / api

授权持票人token_id

nodejs服务器端,我调用以下方法来validation令牌。

exports.verifyUser = function(req, res, next) { var GoogleAuth = require('google-auth-library'); var auth = new GoogleAuth(); var client = new auth.OAuth2(config.passport.google.clientID, config.passport.google.clientSecret, config.passport.google.callbackURL); // check header or url parameters or post parameters for token var token = ""; var tokenHeader = req.headers["authorization"]; var items = tokenHeader.split(/[ ]+/); if (items.length > 1 && items[0].trim().toLowerCase() == "bearer") { token = items[1]; } if (token) { var verifyToken = new Promise(function(resolve, reject) { client.verifyIdToken( token, config.passport.google.clientID, function(e, login) { console.log(e); if (login) { var payload = login.getPayload(); var googleId = payload['sub']; resolve(googleId); next(); } else { reject("invalid token"); } } ) }).then(function(googleId) { res.send(googleId); }).catch(function(err) { res.send(err); }) } else { res.send("Please pass token"); } } 

当我调用上述方法时,我总是得到无效标记响应,并出现以下错误。

 Error: No pem found for envelope: {"alg":"RS256","kid":"c1ab5857066442ea01a01601 850770676460a712"} at OAuth2Client.verifySignedJwtWithCerts (\node_modules\google-auth-libr ary\lib\auth\oauth2client.js:518:13) 
  • 这是validation令牌的正确方法吗?
  • 我是否将id_token作为授权承载发送? 还是仅用于授权?
  • 如何将id_token发送到服务器端? 通过URL,标题?
  • 我究竟做错了什么?

任何帮助,高度赞赏。

OAuth2Client.verifyIdToken从参数库中获取idToken:

 /** * Verify id token is token by checking the certs and audience * @param {string} idToken ID Token. * @param {(string|Array.<string>)} audience The audience to verify against the ID Token * @param {function=} callback Callback supplying GoogleLogin if successful */ OAuth2Client.prototype.verifyIdToken = function(idToken, audience, callback) 

您已经通过了整个标头值bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxYWI1OD U3MDY2NDQyZWEwMWEwMTYwMTg1MDc3MDY3NjQ2MGE3MTIifQ所以你将不得不分裂标题值为:

 var authorization = req.headers["authorization"]; var items = authorization.split(/[ ]+/); if (items.length > 1 && items[0].trim() == "Bearer") { var token = items[1]; console.log(token); // verify token } 

这是validation令牌的正确方法吗?

是的,这是validation令牌的正确方法。 对于debugging,如果您有任何疑问或需要进行快速testing,还可以使用tokeninfo端点validation令牌:

 https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123 
  • 我是否将id_token作为授权承载发送? 还是仅用于授权?
  • 如何将id_token发送到服务器端? 通过URL,标题?

您可以在授权标头中发送JWT令牌,但是如果您有多个授权标头 ,可能会导致出现使用情况。 最好将URL编码或将令牌embedded到主体中。 你可以在这里查看Google示例

此外,Google还需要以下内容:

  • 令牌必须通过HTTPS POST发送
  • 令牌的完整性必须经过validation

为了优化您的代码,您还可以将Google auth对象移动到应用程序根目录的app.js ,而不是在每次validation令牌时重新定义它。 在app.js

 var app = express(); var GoogleAuth = require('google-auth-library'); var auth = new GoogleAuth(); app.authClient = new auth.OAuth2(config.passport.google.clientID, config.passport.google.clientSecret, config.passport.google.callbackURL); 

并在verifyUserreq.app.authClient调用它:

 req.app.authClient.verifyIdToken(...)