Использование Firebase Auth для доступа к API Календаря Google
Я создаю веб-приложение с использованием AngularJS, Firebase (SDK v3) и API Календаря Google. Я аутентифицирую пользователей с помощью 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);
});
Однако, похоже, что за пределами первоначального входа в систему невозможно получить токен доступа Google через Firebase SDK. Кажется, возможно получить доступ только к токену Firebase JWT, но не использовать Calendar API. Я мог бы сохранить токен доступа, но это не решило бы проблемы при обновлении токена и т. Д. Есть ли способ получить текущий токен Google Access с помощью Firebase SDK и, если нет, какие другие решения существуют для этой проблемы, не имея аутентифицировать пользователя дважды?
ОБНОВЛЕНИЕ 1:
Похоже, кто-то еще боролся с подобными проблемами с аутентификацией Facebook. По этому вопросу была ссылка на документацию Firebase, в которой говорилось, что Аутентификация Firebase больше не сохраняет токен доступа. Так как я могу справиться с обновлениями токенов? Неужели нет ответа на этот вопрос?
ОБНОВЛЕНИЕ 2:
Итак, я связался со службой поддержки Firebase с запросом функции по этой проблеме, и они дали мне следующий ответ:
Спасибо, что нашли время написать нам.
Я понял вашу точку зрения, это действительно хорошее предложение. Мы точно знаем, что многим пользователям, таким как вы, нужна функция OAuth, которая будет получать доступ к токену при обновлении. Мы изучаем потенциальные решения, но я не могу гарантировать, что это будет доступно в ближайшее время. Мы будем учитывать ваши отзывы в будущем. Постоянное улучшение очень важно для нашего сообщества, поэтому спасибо за то, что подняли этот вопрос!
Следите за нашими примечаниями к выпуску для любых дальнейших обновлений.
Так что похоже, что токены доступа не доступны через Firebase SDK в данный момент. Я все еще пытаюсь найти обходной путь, поэтому, если у кого-то есть идеи по поводу правильного решения, я буду рад их услышать. И, конечно, я буду публиковать его здесь, если найду работающее решение самостоятельно.
1 ответ
Наконец-то я обошел эту проблему, обработав аутентификацию вне Firebase с помощью JavaScript-клиента Google API. Это решение требует включения клиента авторизации Google, как описано здесь. Обработка потока входа в 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.