如何在节点 js 的服务器端验证 google 身份验证令牌?
How to verify google auth token at server side in node js?
我的前端应用程序使用 gmail 帐户通过身份验证。
我在认证成功后检索id_token作为授权发送Header作为不记名令牌。
授权持有人token_id
在 nodejs 服务器端,我调用以下方法来验证令牌。
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");
}
}
当我调用上述方法时,我总是得到 Invalid 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发送到服务器端?通过 url、header?
- 我做错了什么?
非常感谢任何帮助。
OAuth2Client.verifyIdToken
在参数中取一个 idToken,来自 library source :
/**
* 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)
您已经传递了整个 header 值 bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxYWI1OD U3MDY2NDQyZWEwMWEwMTYwMTg1MDc3MDY3NjQ2MGE3MTIifQ
,因此您必须将 headers 值拆分为:
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?
您可以在授权中发送 JWT 令牌 header 但它可能会导致您有 multiple Authorization headers. It's best to URL encode or embed the token in the body. You can check Google example here
的用例
此外,Google需要以下内容:
- 令牌必须通过 HTTPS 发送 POST
- 必须验证令牌完整性
要优化您的代码,您还可以将 Google auth
object 移动到应用程序根目录下的 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.clientSecret, config.passport.google.callbackURL);
并在 verifyUser
中从 req.app.authClient
调用它:
req.app.authClient.verifyIdToken(...)
今天终于找到答案了。
Firebase工具会把原生的Google连接到第三方的login token,然后再封装一层。此时获得的token已经不是原来Google.
给我们的token了
- A1:
- 原始令牌:
GoogleDesignInAccount Account = Task.getResult(ApiException.class);
Account.getidToken () // This is the original token
- B1:
- Firebase 令牌:
FireBaseUser currentUser = Mauth.getCurrentUser ();
String token = currentUser.getIdToken(false).getResult().getToken();
- A2:
- Google官方提供了验证token的方法
- B2:
- Firebase官方提供token认证方式
我们对以上四个数据点使用代号。如果需要在后台验证token的合法性,必须要一一对应,A1对A2,B1对B2。如果用A2验证B1,会失败
我的前端应用程序使用 gmail 帐户通过身份验证。
我在认证成功后检索id_token作为授权发送Header作为不记名令牌。
授权持有人token_id
在 nodejs 服务器端,我调用以下方法来验证令牌。
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");
}
}
当我调用上述方法时,我总是得到 Invalid 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发送到服务器端?通过 url、header?
- 我做错了什么?
非常感谢任何帮助。
OAuth2Client.verifyIdToken
在参数中取一个 idToken,来自 library source :
/**
* 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)
您已经传递了整个 header 值 bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxYWI1OD U3MDY2NDQyZWEwMWEwMTYwMTg1MDc3MDY3NjQ2MGE3MTIifQ
,因此您必须将 headers 值拆分为:
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?
您可以在授权中发送 JWT 令牌 header 但它可能会导致您有 multiple Authorization headers. It's best to URL encode or embed the token in the body. You can check Google example here
的用例此外,Google需要以下内容:
- 令牌必须通过 HTTPS 发送 POST
- 必须验证令牌完整性
要优化您的代码,您还可以将 Google auth
object 移动到应用程序根目录下的 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.clientSecret, config.passport.google.callbackURL);
并在 verifyUser
中从 req.app.authClient
调用它:
req.app.authClient.verifyIdToken(...)
今天终于找到答案了。 Firebase工具会把原生的Google连接到第三方的login token,然后再封装一层。此时获得的token已经不是原来Google.
给我们的token了- A1:
- 原始令牌:
GoogleDesignInAccount Account = Task.getResult(ApiException.class);
Account.getidToken () // This is the original token
- 原始令牌:
- B1:
- Firebase 令牌:
FireBaseUser currentUser = Mauth.getCurrentUser ();
String token = currentUser.getIdToken(false).getResult().getToken();
- Firebase 令牌:
- A2:
- Google官方提供了验证token的方法
- B2:
- Firebase官方提供token认证方式
我们对以上四个数据点使用代号。如果需要在后台验证token的合法性,必须要一一对应,A1对A2,B1对B2。如果用A2验证B1,会失败