我的前端应用程序使用gmail帐户进行身份验证.
我在身份验证成功后检索id_token,并将其作为授权标头发送为承载令牌.
授权承载token_id
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)
>这是验证令牌的正确方法吗?
>我是否将id_token作为授权持有者发送?或者只是授权?
>如何将id_token发送到服务器端?通过网址,标题?
>我做错了什么?
任何帮助都非常感谢.
解决方法
OAuth2Client.verifyIdToken从
library source中获取参数中的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)
你已经传递了整个标题值的持有者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 }
Is this the right approach to verify token ?
是的,这是验证令牌的正确方法.对于调试,如果您有任何疑问或进行快速测试,还可以使用tokeninfo端点验证令牌:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
- Do I send the id_token as Authorization bearer? Or is it for
authorization only?- How do I send the id_token to the sever side? Thru
url,header?
您可以在Authorization标头中发送JWT令牌,但它可能会导致您拥有multiple Authorization headers的用例.最好对令牌进行URL编码或嵌入正文.您可以查看Google示例here
此外,Google还需要以下内容:
>必须通过HTTPS POST发送令牌
>必须验证令牌完整性
要优化代码,您还可以将Google身份验证对象移至应用根目录下的app.js,而不是每次验证令牌时重新定义它.在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.callbackURL);
并在verifyUser中从req.app.authClient调用它:
req.app.authClient.verifyIdToken(...)