ApolloServer 2.0 上下文和 GraphQL API 的 public/private 部分
ApolloServer 2.0 context and public/private parts of the GraphQL API
我在任何方面都不是专业人士,但我已经开始 ApolloServer/Express 后端托管一个站点,我将在其中为成员提供 public 部分和私人部分。我在登录突变中生成 JWT 令牌并将其交付给客户端。
根据上下文,我想检查是否设置了令牌,并基于此处理允许哪些 GraphQL 查询。我的 Express/Apollo 服务器目前看起来像这样。
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
// get the user token from the headers
const token = (await req.headers.authorization) || '';
if (token) {
member = await getMember(token);
}
}
});
问题是,这会锁定 GraphQL API 以防止任何查询,例如,我 want/need 无法达到 signup/login 突变。
任何人都可以阐明这一点,以帮助我理解我需要做什么才能让它发挥作用。
我这样做的方式是,我什至会在 graphql 服务器之前构建 auth 中间件,因为有时需要在其他中间件中获得有关经过身份验证的用户的信息,而不仅仅是 GraphQL 模式。将添加一些代码,你需要完成它
const auth = (req, res, next) => {
if (typeof req.headers.authorization !== 'string') {
return next();
}
const header = req.headers.authorization;
const token = header.replace('Bearer ', '');
try {
const jwtData = jwt.verify(token, JWT_SECRET);
if (jwtData && jwtData.user) {
req.user = jwtData.user;
} else {
console.log('Token was not authorized');
}
} catch (err) {
console.log('Invalid token');
}
return next();
};
如果设置了正确的令牌,我将通过这种方式将用户注入到每个请求中。然后在apollo server 2中你可以按如下方式进行。
const initGraphQLserver = () => {
const graphQLConfig = {
context: ({ req, res }) => ({
user: req.user,
}),
rootValue: {},
schema,
};
const apolloServer = new ApolloServer(graphQLConfig);
return apolloServer;
};
此函数将启动 ApolloServer,您将在正确的位置应用此中间件。 applyin apollo server 2
之前需要有auth中间件
app.use(auth);
initGraphQLserver().applyMiddleware({ app });
假设应用是
const app = express();
现在,您会将来自用户 jwtData 的用户作为 "user" 注入到每个解析器的上下文中,或者在其他中间件中的 req.user 中,您可以像这样使用它。这是我查询说明哪个用户已通过身份验证
me: {
type: User,
resolve: async (source, args, ctx) => {
const id = get(ctx, 'user.id');
if (!id) return null;
const oneUser = await getOneUser({}, { id, isActive: true });
return oneUser;
},
},
我希望即使使用分段代码,一切都有意义。如有任何问题,请随时提出。肯定有更复杂的 auth,但是这个基本示例通常对于简单的应用程序来说已经足够了。
最佳大卫
我在任何方面都不是专业人士,但我已经开始 ApolloServer/Express 后端托管一个站点,我将在其中为成员提供 public 部分和私人部分。我在登录突变中生成 JWT 令牌并将其交付给客户端。
根据上下文,我想检查是否设置了令牌,并基于此处理允许哪些 GraphQL 查询。我的 Express/Apollo 服务器目前看起来像这样。
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
// get the user token from the headers
const token = (await req.headers.authorization) || '';
if (token) {
member = await getMember(token);
}
}
});
问题是,这会锁定 GraphQL API 以防止任何查询,例如,我 want/need 无法达到 signup/login 突变。
任何人都可以阐明这一点,以帮助我理解我需要做什么才能让它发挥作用。
我这样做的方式是,我什至会在 graphql 服务器之前构建 auth 中间件,因为有时需要在其他中间件中获得有关经过身份验证的用户的信息,而不仅仅是 GraphQL 模式。将添加一些代码,你需要完成它
const auth = (req, res, next) => {
if (typeof req.headers.authorization !== 'string') {
return next();
}
const header = req.headers.authorization;
const token = header.replace('Bearer ', '');
try {
const jwtData = jwt.verify(token, JWT_SECRET);
if (jwtData && jwtData.user) {
req.user = jwtData.user;
} else {
console.log('Token was not authorized');
}
} catch (err) {
console.log('Invalid token');
}
return next();
};
如果设置了正确的令牌,我将通过这种方式将用户注入到每个请求中。然后在apollo server 2中你可以按如下方式进行。
const initGraphQLserver = () => {
const graphQLConfig = {
context: ({ req, res }) => ({
user: req.user,
}),
rootValue: {},
schema,
};
const apolloServer = new ApolloServer(graphQLConfig);
return apolloServer;
};
此函数将启动 ApolloServer,您将在正确的位置应用此中间件。 applyin apollo server 2
之前需要有auth中间件app.use(auth);
initGraphQLserver().applyMiddleware({ app });
假设应用是
const app = express();
现在,您会将来自用户 jwtData 的用户作为 "user" 注入到每个解析器的上下文中,或者在其他中间件中的 req.user 中,您可以像这样使用它。这是我查询说明哪个用户已通过身份验证
me: {
type: User,
resolve: async (source, args, ctx) => {
const id = get(ctx, 'user.id');
if (!id) return null;
const oneUser = await getOneUser({}, { id, isActive: true });
return oneUser;
},
},
我希望即使使用分段代码,一切都有意义。如有任何问题,请随时提出。肯定有更复杂的 auth,但是这个基本示例通常对于简单的应用程序来说已经足够了。
最佳大卫