Мне нужна помощь, чтобы получить облачную функцию Firebase Apollo / GraphQL для аутентификации и получения запросов.
Функция Apollo / GraphQL отлично работает (протестировано с детской площадкой) , когда права доступа установлены на allUsers
. После установки разрешений на allAuthenticatedUsers
и попытки отправки аутентифицированных запросов я получаю следующее сообщение об ошибке:
Bearer error="invalid_token" error_description="The access token could not be verified"
Я считаю, что я делаю ошибку с запросом, отправленным клиентом и или обработки проверки и «контекста» ApolloServer. Я подтвердил, что начальный токен пользователя правильный. Моя текущая теория заключается в том, что я отправляю неправильный заголовок или каким-то образом путаю синтаксис на уровне клиента или сервера.
Для объяснения того, что, по моему мнению, должен выполняться соответствующий поток запроса:
- Токен, сгенерированный в клиенте
- Запрос, отправленный от клиента с токеном в качестве заголовка
- Облачная функция ApolloServer получает запрос
- Токен проверен Firebase, предоставляет новый проверенный токен заголовка
- Сервер принимает запрос с новым проверенным токеном заголовка и возвращает данные
Если кто-нибудь может объяснить, как отправлять действительные аутентифицированные клиентские запросы в облачную функцию Firebase Apollo / GraphQL, то помощь будет принята с благодарностью. Код для сервера и клиента ниже.
Сервер. js (ApolloServer)
/* Assume proper imports */
/* Initialize Firebase Admin SDK */
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "[db-url]",
});
/* Async verification with user token */
const verify = async (idToken) => {
var newToken = idToken.replace("Bearer ", "");
let header = await admin.auth().verifyIdToken(newToken)
.then(function(decodedToken) {
let uid = decodedToken.uid;
// Not sure if I should be using the .uid from above as the token?
// Also, not sure if returning the below object is acceptable, or
// if this is even the correct header to send to firebase from Apollo
return {
"Authorization": `Bearer ${decodedToken}`
}
}).catch(function(error) {
// Handle error
return null
});
return header
}
/* Server */
function gqlServer() {
const app = express();
const apolloServer = new ApolloServer({
typeDefs: schema,
resolvers,
context: async ({ req, res }) => {
const verified = await verify(req.headers.Authorization)
console.log('log verified', verified)
return {
headers: verified ? verified: '',
req,
res,
}
},
// Enable graphiql gui
introspection: true,
playground: true
});
apolloServer.applyMiddleware({app, path: '/', cors: true});
return app;
}
export default gqlServer;
Клиент. js (ApolloClient)
Клиентский запрос, построенный с использованием этих инструкций .
/* Assume appropriate imports */
/* React Native firebase auth */
firebase.auth().onAuthStateChanged(async (user) => {
const userToken = await user.getIdToken();
/* Client creation */
const client = new ApolloClient({
uri: '[Firebase Cloud Function URL]',
headers: {
Authorization: userToken ? `Bearer ${userToken}` : ''
},
cache: new InMemoryCache(),
});
/* Query test */
client.query({
query: gql`
{
hello
}
`
}).then(
(result) => console.log('log query result', result)
).catch(
(error) => console.log('query error', error)
)
})
ОБНОВЛЕНИЕ 05/03/20
Возможно, я нашел источник ошибки. Я не буду публиковать ответ, пока не подтвердлю, но вот обновление. Похоже, allAuthenticatedUsers
- это роль, определяемая c для учетных записей Google, а не Firebase. См. эту часть google docs и этот ответ stackoverflow .
Я проведу некоторое тестирование, но решение может заключается в изменении разрешений на allUsers
, что может потребовать аутентификации. Если я смогу заставить это работать, я обновлю с ответом.