如何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);
并在verifyUser
从req.app.authClient
调用它:
req.app.authClient.verifyIdToken(...)