如何将 Firebase Auth Token 从客户端传递到服务器?
Posted
技术标签:
【中文标题】如何将 Firebase Auth Token 从客户端传递到服务器?【英文标题】:How to pass Firebase Auth Token from client to server? 【发布时间】:2017-08-28 23:13:49 【问题描述】:我正在处理的网站使用 Firebase 身份验证,并且登录的不同用户对于他们可以访问哪些页面具有不同的权限。
登录的设置方式和这个post类似:
-
用户使用两个参数登录 - “id”和“email”
服务器使用这些来创建一个自定义“uid”,然后使用 Firebase Admin SDK 创建一个发送回客户端的自定义令牌。
客户端使用 javascript Firebase SDK - firebase.auth().signInWithCustomToken() 登录
现在用户已登录,他们可以点击不同的页面 - 即“/foo”、“/bar”
我遇到的问题是,当他们访问新页面时,我试图将令牌从客户端传递回服务器(几乎与它在 Firebase Doc 中的完成方式相同),验证令牌并检查它是否有权查看该网页。
我正在尝试找出最好的(也是最安全的)方法来做到这一点。我考虑过以下选项:
使用令牌构造一个 URL,但我听说这不是一个好的做法,因为令牌会暴露出来,会话劫持变得容易得多。我一直在尝试在请求标头中传递令牌,但据我了解,当用户单击指向不同页面的链接(或者如果它在 javascript 中重定向)时,您无法添加标头。同样的问题也适用于使用 POST。
当用户单击指向不同页面的链接时,我可以做些什么来安全地将这些信息传递给服务器并检查权限?
【问题讨论】:
您可以将其设置在 cookie 中。这就是我可能会做的。 嗨,迈克尔,非常感谢您的回复。我需要服务器上的信息,但会话是我没有想到的。但这似乎不起作用,因为即使我将客户端的令牌 或 自定义 uid 存储在服务器上,客户端仍然需要发送其中一个才能访问正确的会话数据.这仍然使会话劫持非常容易.. 我也遇到了同样的问题,你是怎么解决的? 【参考方案1】:您可以通过以下方式获取客户端的accessToken(idToken):
var accessToken = null;
firebase.auth().currentUser
.getIdToken()
.then(function (token)
accessToken = token;
);
并将其传递到您的请求标头中:
request.headers['Authorization'] = 'Bearer ' + accessToken;
然后在您的服务器端使用您喜欢的方法获取令牌并使用 Firebase Admin SDK 对请求进行身份验证,例如 (Node.js):
firebaseAdmin.auth()
.verifyIdToken(accessToken)
.then(decodedIdToken =>
return firebaseAdmin.auth().getUser(decodedIdToken.uid);
)
.then(user =>
// Do whatever you want with the user.
);
【讨论】:
您是否真的必须创建令牌才能让我在客户端检索它?【参考方案2】:现在,我们似乎打算使用httpsCallable()
客户端来获得一个预先授权的对象来与您的端点通信。
例如:
// # ./functions/index.js
exports.yourFunc = functions.https.onCall((data, context) =>
// Checking that the user is authenticated.
if (!context.auth)
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
// ... rest of your method
);
// ./src/models/addMessage.js
const firebase = require("firebase");
require("firebase/functions");
firebase.initializeApp(
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
projectId: '### CLOUD FUNCTIONS PROJECT ID ###'
databaseURL: 'https://### YOUR DATABASE NAME ###.firebaseio.com',
);
var functions = firebase.functions();
// This is the new code:
var yourFunc = firebase.functions().httpsCallable('yourFunc');
yourFunc(foo: bar).then(function(result)
// ...
);
来自firebase documentation
【讨论】:
以上是关于如何将 Firebase Auth Token 从客户端传递到服务器?的主要内容,如果未能解决你的问题,请参考以下文章
firebase:admin.auth().updateUser() 导致 auth/user-token-expired
Flutter-Firebase phone Auth 总是在 iOS 上返回 Token mismatch