如何在Firestore Cloud Functions上使用Apollo Server GraphQL在TypeScr



我一直在看这篇文章,但试图用TypeScript而不是JavaScript来做这件事:https://medium.com/@piuccio上运行-阿波罗-服务器- -重火力点-云-功能- 265849 e9f5b8

然而,当Authorization标头未正确提供时,我无法获得正确的行为。在下面的代码中,我抛出了一个Error("No token")。我还试图返回一个被拒绝的Promise,但这给了我一个HTTP 500错误与{}(空JSON响应)。

import gql from 'graphql-tag';
import { makeExecutableSchema } from 'graphql-tools';
import { Config } from 'apollo-server-cloud-functions';
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

... resolvers, etc go here...

async function getUser(token: string): Promise<admin.auth.DecodedIdToken> {
functions.logger.info('token', token);
if (token === undefined || token === '') {
throw new Error("No token");
}
const idToken = token.split('Bearer ')[1];
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
return decodedIdToken;
}
export const config: Config = {
schema: makeExecutableSchema({
typeDefs,
resolvers,
}),
// TODO: DISABLE THESE IN PRODUCTION!
introspection: true,
playground: true,
context: ({req, context}): Promise<admin.auth.DecodedIdToken> => {
// See https://www.apollographql.com/docs/apollo-server/security/authentication/
functions.logger.info('req headers', req.headers);
const token = req.headers.authorization || '';
const user = getUser(token);
// if (!user) throw new AuthenticationError('you must be logged in');
return user;
},
formatError: formatError,
};

对于API支持匿名访问的情况,我如何从getUser()返回有效的Promise?

我更愿意使用阿波罗服务器AuthenticationError(作为我的身份验证检查),但我不能从getUser()返回null

以下的建议在这里:如何拒绝在async/await语法?

我可以将Promise的类型修改为DecodedIdToken | null,并返回null作为有效值。如果我rejectPromise,那么抛出一个异常与错误字符串。

async function getUser(token: string): Promise<DecodedIdToken | null> {
functions.logger.info('token', token);
if (token === undefined || token === '') {
return null;
// return Promise.reject("No token");
}
const idToken = token.split('Bearer ')[1];
const decodedIdToken = admin.auth().verifyIdToken(idToken);
return decodedIdToken;
}
export const config: Config = {
schema: makeExecutableSchema({
typeDefs,
resolvers,
}),
// TODO: DISABLE THESE IN PRODUCTION!
introspection: true,
playground: true,
context: async ({req, context}): Promise<DecodedIdToken | null> => {
// See https://www.apollographql.com/docs/apollo-server/security/authentication/
functions.logger.info('req headers', req.headers);
const token = req.headers.authorization || '';
try {
const user = await getUser(token);
return Promise.resolve(user);
} catch (err) {
return Promise.resolve(null); // "No token"
// throw new AuthenticationError('you must be logged in');
}
},
formatError: formatError,
};

因此,取决于你是否想要抛出异常,或者如果你想使用自己的异常(如FireStore的AuthenticationError),你可以按照你想要的方式构建它。

以下是不同的选项:

Promise.resolve(value)
Promise.resolve(null)
Promise.reject("Not valid")  -> throws exception Error("Not valid")
throw new AuthenticationError("Not authorized")

…或者使用构造函数语法:

return new Promise<DecodedIdToken | null>((resolve, reject) => {
if (valid) {
resolve(value);
} else {
reject("Not valid");
}
});

最新更新