我使用Google Endpoints作为API网关,它运行在Google Run容器服务中。API路径指向Google Function(节点js)。对API网关的调用来自Web应用程序(即浏览器)。
其中一条路径是:/login
,它使用firebase.auth().signInWithEmailAndPassword
方法在firebase中对用户进行身份验证。我获取用户的令牌ID,并将其在响应报头(身份验证载体)中发送回浏览器。这按预期工作。
当有其他请求(例如/check
)发送到端点时,令牌(在头中)会被包含。我想在处理任何请求之前使用Firebase Admin方法检查令牌的有效性。Google函数中为其中一个路由执行此操作的代码如下:
...
const decodeIdToken = async (req, res, next) => {
// Read the ID Token from the Authorization header.
const idToken = req.headers.authorization.split('Bearer ')[1];
try {
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
req.decodedToken = decodedIdToken;
next();
return;
} catch (error) {
return res.status(403).json({
status: 'failure',
data: null,
error: error.message
});
}
};
// use decodeIdToken as middleware
app.post('/check', decodeIdToken, (req, res, next) => {
return res.json({
status: 'success',
data: req.decodedToken,
error: null
});
});
当我通过直接调用Google Function触发器来调用(通过Postman)路由时,两个路由都有效。但是,当我调用指向Google Function的Google Endpoints时,我在使用Firebase Admin对象时收到以下错误:
Firebase ID令牌具有不正确的\“aud\”(audience)声明。应为\“PROJECT-ID\”,但得到的是\”https://us-central1-PROJECT-ID.cloudfunctions.net/FUNCTION-NAME"。请确保ID令牌与用于验证此SDK的服务帐户来自同一Firebase项目。有关如何检索ID令牌的详细信息,请参见https://firebase.google.com/docs/auth/admin/verify-id-tokens
在NodeJ中设置Firebase Admin对象时,我尝试了以下操作:
const admin = require('firebase-admin');
admin.initializeApp();
以及
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://PROJECT-ID.firebaseio.com"
});
3条答案
按热度按时间qyswt5oh1#
使用
X-Apigateway-Api-Userinfo
信头标头的值是JWT的base64编码有效负载。由于API Gateway已经为您验证了标记并使内容可供您使用,因此不需要重新验证。
Node.js开发示例:
无论出于什么原因,如果您确实需要访问原始JWT,则可以在
X-Forwared-Authorization
头文件中找到它。不必要的额外学分:
为了解释这个错误,您得到错误受众声明的原因是因为您尝试验证的JWT是由API Gateway生成的不同JWT。原始授权头被替换为这个JWT。为什么?它告诉云功能“嘿,云功能,是我的API Gateway在呼叫您,这里有一个签名的JWT可以证明这一点”。因此,API Gateway的受众最终是Cloud Function资源URL,而Firebase的受众是的受众是Firebase所在的项目。
如果你问我的话,这只是另一个奇怪的不便的例子,由于谷歌的实现;他们完全可以保留Auth头,让API Gateway使用不同的头,但乞丐不能挑肥拣瘦。🤷♂️
Reference API Gateway Documentation:
在API中接收经过身份验证的结果
API网关通常会转发它接收到的所有头。但是,当后端地址在API配置中由x-google-backend指定时,它会覆盖原始的授权头。
API网关会将X-Apigateway-Api-Userinfo中的验证结果发送到后端API。建议使用此标头而不是原始授权标头。此标头采用base64 url编码,并包含JWT有效负载。
iibxawm42#
以下工作不起作用(见下面的注解):
在
openapi-functions.yaml
中添加文档建议的安全定义然后,针对路径(在我的例子中为
/check
)添加security部分,如下所示:请参阅:https://cloud.google.com/endpoints/docs/openapi/authenticating-users-firebase
dwbf0jvd3#
你的admin-sdk设置没有问题,它是idToken,实际上是一个jwt令牌,在使用firebase登录时返回为idToken。
您的问题是您试图使用由auth()函数之一(如firebase.auth().signInWithEmailAndPassword)返回的JWT标记(作为idToken)。这些函数确实返回了JWT标记,但是auth声明可能是错误的,不会通过verifyIdToken的验证。
你必须使用firebase.auth().currentUser.getToken()函数,这个令牌将通过验证。