egg
egg copied to clipboard
关于 egg-graphql 鉴权部分有什么好的方案
graphql 在授权这块目前有好的方案吗?
参考之前的 issue 总共两种方案:
- 授权代码分散在每个业务的
resolver里 - 加中间件拦截
登录验证之类的,分散在各个业务 resolver 里确实不友好。加中间件方式 query 里面全是字符串,要手动去解析或正则匹配吗?都感觉都不太理想。
type Query {
# 登录
login(username: String! password: String!): User!
# 登出
logout: Result!
# 用户
user(id: Int): User!
# 用户列表
userList(input: UserQueryInput): UserResult!
}
请问大家有什么好的方式推荐吗,或贴伪代码?
刚刚看到 graphql 可以用指令的形式指定权限,不知道这种方式有什么弊端
# I want posts to only be readable by logged-in users
type Post @isLoggedIn {
id: ID
content: String
author: User()
notes: [String] @isAuthor # I want these to only be accessible by the author
}
在 egg-graphql 中
https://github.com/eggjs/egg-graphql/blob/master/lib/load_schema.js#L52
this[SYMBOL_SCHEMA] = makeExecutableSchema({
typeDefs: schemas,
resolvers: resolverMap,
directiveResolvers: directiveMap,
});
只传入了3个参数,要实现上述评论的权限指令根本不行。
在 graphql-tools 中
https://github.com/apollographql/graphql-tools/blob/48b4c12100b0d517f596a47d830afc77bfe471f9/src/schemaGenerator.ts#L117
makeExecutableSchema API 是有 schemaDirectives 这个参数的。
在这篇教程中,
https://github.com/apollographql/graphql-tools/blob/42c7296943e3e6bd8cf2173ef74863a196cd2e14/docs/source/schema-directives.md
是介绍 schemaDirectives 强大的指令实现。
egg-graphql 应该考虑将 schemaDirectives 参数加入进去?
@jtyjty99999
ok 我支持一下,之前鉴权都是中间件做的
我参照 egg-graphql 重新搞了个:egg-graphql-apollo
官方的库不太能接受,问题如下:
app/graphql下的每个业务目录都包含相同名称的文件,在编辑器打开很容易混淆,稍微不注意就写错地方。graphql-tools推荐connector是直连数据库的。因为egg中有service,所以resolver.js可以直接调用service,connector.js没必要存在。- 官方库目前没支持
schemaDirectives,不能很好做鉴权。
@MinJieLiu 支持一波,schemaDirectives 要比 directiveResolvers 强大很多,官方现在推荐 schemaDirectives 的方式来实现指令
@MinJieLiu 因为 graphql-tools 最近又改了 api,2.19.0 里面是使用的 directiveResolvers 。
使用 Directive 来做鉴权是没有问题的,但是 graphql-tools 应该只支持对 Field 来做拦截。
https://github.com/apollographql/graphql-tools/blob/48b4c12100b0d517f596a47d830afc77bfe471f9/src/schemaGenerator.ts#L697-L715
这段代码可以看出来是给有 Directive 的 field 加了一个 resolver 做了拦截。
所以对于 type Post @isLoggedIn 应该需要吧 @isLoggedIn 放到 Post 的 Query 操作里面
@jtyjty99999 https://github.com/eggjs/egg-graphql/blob/master/app/middleware/graphql.js#L28
这里有个问题,不应该用 return 这样会导致后面的中间件不执行,比如 csrf 等。应该换成 await,有空也一起改一下吧
@foreleven type Post @isLoggedIn 是可以的。directiveResolvers 最后都是合并到 schemaDirectives 里,因此可以直接使用schemaDirectives API。
https://github.com/apollographql/graphql-tools/blob/42c7296943e3e6bd8cf2173ef74863a196cd2e14/docs/source/schema-directives.md#enforcing-access-permissions
我还以为是走了 graphql 后故意让后面的中间件不执行呢😊