我正在使用AngularJS,Firebase(SDK v3)和Google Calendar API构建Web应用程序。我正在使用Google OAuth对用户进行身份验证。我的目的是能够从Firebase中的数据库节点创建日历事件。到目前为止,我设法通过以下方法请求访问日历范围:
_authProvider = new firebase.auth.GoogleAuthProvider(); // Get permission to manage Calendar _authProvider.addScope("https://www.googleapis.com/auth/calendar"); _fbAuthObject.signInWithRedirect(_authProvider);
我正在使用重定向流进行身份验证,因此身份验证重定向可用于:
_fbAuthObject.getRedirectResult() .then(function _readToken(result) { if (result.credential) { _googleToken = result.credential.accessToken; var authHeader = 'Bearer '+ _googleToken; // Just a test call to the api, returns 200 OK $http({ method: 'GET', headers: { 'Authorization': authHeader }, url: 'https://www.googleapis.com/calendar/v3/users/me/calendarList/primary' }) .then(function success(response) { console.log('Cal response', response); }, function error(response) { console.log('Error', response); });
但是,似乎在首次登录后,无法通过Firebase SDK获取Google访问令牌。似乎只能访问Firebase JWT令牌,而不能与Calendar API一起使用。我可以存储访问令牌,但这在刷新令牌等时无法解决问题。有什么方法可以使用Firebase SDK获取当前的Google Access令牌,如果没有,可以使用什么其他解决方案来解决该问题两次验证用户身份?
更新1:
似乎其他人正在为Facebook身份验证遇到类似问题。在该问题上,有一个指向Firebase文档的链接,指出Firebase身份验证不再保留访问令牌。那么我该如何处理令牌刷新呢?真的没有答案吗?
更新2:
因此,我联系Firebase支持并提供了有关此问题的功能请求,他们给了我以下答案:
感谢您抽出宝贵时间给我们写信。 我的意思是,这确实是一个好建议。我们肯定知道许多用户(例如您自己)希望使用OAuth功能,该功能将在刷新后访问令牌。我们正在探索潜在的解决方案,但我不能保证它是否会很快出现。我们会继续考虑您的反馈意见。持续改进对我们的社区非常重要,因此感谢您提出! 请留意我们的发行说明以获取任何进一步的更新。
感谢您抽出宝贵时间给我们写信。
我的意思是,这确实是一个好建议。我们肯定知道许多用户(例如您自己)希望使用OAuth功能,该功能将在刷新后访问令牌。我们正在探索潜在的解决方案,但我不能保证它是否会很快出现。我们会继续考虑您的反馈意见。持续改进对我们的社区非常重要,因此感谢您提出!
请留意我们的发行说明以获取任何进一步的更新。
因此,目前看来访问令牌无法通过FirebaseSDK获得。我仍在尝试寻找解决方法,因此,如果有人对有效的解决方案有任何想法,我将很高兴听到它们。当然,如果我自己找到可行的解决方案,我会在此处发布。
通过使用Google APIJavaScript客户端在Firebase外部处理身份验证,终于解决了这个问题。此解决方案需要包括此处记录的Google auth客户端。此处记录了手动处理Firebase登录流程。
gapi.auth2.getAuthInstance().signIn() .then(function _firebaseSignIn(googleUser) { var unsubscribe = firebase.auth().onAuthStateChanged(function(firebaseUser) { unsubscribe(); // Check if we are already signed-in Firebase with the correct user. if (!_isUserEqual(googleUser, firebaseUser)) { // Build Firebase credential with the Google ID token. var credential = firebase.auth.GoogleAuthProvider.credential( googleUser.getAuthResponse().id_token); // Sign in with credential from the Google user. return firebase.auth().signInWithCredential(credential) .then(function(result) { // other stuff... });
_isUserEqual函数:
function _isUserEqual(googleUser, firebaseUser) { if (firebaseUser) { var providerData = firebaseUser.providerData; for (var i = 0; i < providerData.length; i++) { if (providerData[i].providerId === firebase.auth.GoogleAuthProvider.PROVIDER_ID && providerData[i].uid === googleUser.getBasicProfile().getId()) { // We don't need to reauth the Firebase connection. return true; } } } return false; }
现在,我可以像这样引用访问令牌:
var user = gapi.auth2.getAuthInstance().currentUser.get(); return user.getAuthResponse().access_token;
对于我来说,这仍然不是理想的解决方案,但它现在可以使用,并且我能够通过Firebase和Calendar API进行身份验证。