阿波罗。如何在没有 jwt 令牌检查的情况下允许 login/registration 查询?

Apollo. How to allow login/registration queries without jwt token check?

如何在没有 jwt 令牌检查的情况下允许 login/registration 查询?

我在为 Apollo 中的登录/注册查询获取 jwt 令牌时遇到问题。我试图了解如何不检查查询(突变)登录/注册的正确性 jwt 令牌。例如,对于我的应用程序中的首次登录,我没有令牌,因此空字符串或 null 或未定义不正确,我无法调用查询登录/注册。

我尝试在上下文中检查令牌。

const getTokenPayload = async (token?: string) => {
  try {
    return await jwt.verify(token, config.jwtSalt);
  } catch (e) {
    throw new ApolloError(`Token doesn't valid`, errorCodes.ERROR_TOKEN_IS_NOT_VALID);
  }
};

const apolloServerStart = (store) => {
  const server = new ApolloServer({
    context: async ({ req }) => {
      const tokenPayload = await getTokenPayload(req.headers.authorization);

      return {
        userId: tokenPayload.id,
      };
    },
    typeDefs,
    resolvers,
    dataSources: () => ({
      userAPI: new UserAPI({ store }),
      cardSetAPI: new CardSetAPI({ store }),
    }),
  });

  const app = express();
  server.applyMiddleware({ app });

  app.listen(
    { port: 4000 },
    () => console.log(`Server ready at http://localhost:4000${server.graphqlPath}`) // eslint-disable-line no-console
  );
};

connectToDb(apolloServerStart);

实例化 ApolloServer 时,在上下文生成函数中,如果缺少 JWT,您绝不能抛出任何错误。

context: async ({ req }) => {
  let userId = null;
  try {
    const tokenPayload = await jwt.verify(req.headers.authorization, config.jwtSalt);
    userId = tokenPayload?.id;
  } catch (err) {}

  return {
    userId
  };
}

上面的代码,无论 JWT 是否为 invalid/missing,都会让每个请求都传递给解析器。 因此,您必须保护您的 PRIVATE 解析器(确保只有登录用户的请求才能到达它们)。为此,您可以定义所谓的 "Guard"。这是一个包装解析器的函数,检查 userId 是否存在于上下文中,并且 returns 在令牌无效(userId 为空)的情况下向客户端发送错误。

只需将您所有的私有解析器包装在保护函数中即可。 不要用 GUARD 函数包装登录和注册解析器。这样,非认证用户就可以调用它们了!