配置
这是 GraphQL 库版本 6 的文档。对于长期支持 (LTS) 版本 5,请参阅 GraphQL 库版本 5 LTS. |
Neo4j GraphQL 库使用 JSON Web Token (JWT) 身份验证。JWT 是包含有关发出请求的用户或客户端的声明或语句的令牌。这些声明可以包括用户信息,例如用户 ID 或角色。
可以从身份验证服务获取 JWT,然后将其包含在 API 请求中。API 会验证 JWT,如果 JWT 有效,则返回请求的数据。
实例化
Neo4j GraphQL 库可以接受两种类型的 JWT
-
请求上下文
token
字段中的编码 JWT。 -
请求上下文
jwt
字段中的解码 JWT。
编码 JWT
为了使用编码 JWT,请使用密钥配置库以解码和验证令牌。以下代码块使用 Apollo Server。它从请求中提取 Authorization
标头,并将其放入适当的上下文字段
const server = new ApolloServer({
schema, // schema from Neo4jGraphQL.getSchema()
});
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
context: async ({ req }) => ({
token: req.headers.authorization,
}),
});
或者,如果需要自定义解码机制,则可以解码相同的标头,并将生成的 JWT 负载放入上下文的 jwt
字段中。
或者,您可以通过 JWKS 端点 解码令牌。
对称密钥
要使用对称密钥 (例如 "secret") 配置库,需要进行以下实例化
new Neo4jGraphQL({
typeDefs,
features: {
authorization: {
key: "secret",
},
},
});
JWKS 端点
要配置库以针对 JSON Web Key Set (JWKS) 端点 (例如 "https://www.example.com/.well-known/jwks.json") 验证令牌,需要进行以下实例化
new Neo4jGraphQL({
typeDefs,
features: {
authorization: {
key: {
url: "https://www.myapplication.com/.well-known/jwks.json"
},
},
},
});
传入编码 JWT
要传入编码 JWT,请使用上下文的 token 字段。使用 Apollo Server 时,将授权标头提取到上下文的 token 属性中
const server = new ApolloServer({
schema,
});
await startStandaloneServer(server, {
context: async ({ req }) => ({ token: req.headers.authorization }),
});
例如,具有以下 authorization
标头的 HTTP 请求应如下所示
POST / HTTP/1.1
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJyb2xlcyI6WyJ1c2VyX2FkbWluIiwicG9zdF9hZG1pbiIsImdyb3VwX2FkbWluIl19.IY0LWqgHcjEtOsOw60mqKazhuRFKroSXFQkpCtWpgQI
content-type: application/json
或者,您可以将类型为 JwtPayload
的键 jwt
传入上下文,该键具有以下定义
// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
interface JwtPayload {
[key: string]: any;
iss?: string | undefined;
sub?: string | undefined;
aud?: string | string[] | undefined;
exp?: number | undefined;
nbf?: number | undefined;
iat?: number | undefined;
jti?: string | undefined;
}
不要传入标头或签名。 |
解码 JWT
解码 JWT 传入上下文的方式与编码 JWT 类似。但是,它使用 jwt
字段而不是使用 token
const jwt = customImplementation();
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
context: async ({ req }) => ({
jwt: jwt,
}),
});
customImplementation
是为提供解码 JWT 的函数的占位符。在 context
中使用 jwt
而不是 token
会告知 Neo4j GraphQL 库不需要解码它。
添加 JWT 声明
默认情况下,过滤对 JWT 规范中的 注册的声明名称 可用。
可以使用 @jwt
指令以及某些情况下的 @jwtClaim
指令,为其他 JWT 声明配置过滤。
@jwt
指令
如果配置了其他 roles
声明,它是一个位于 JWT 负载根目录下的字符串数组,请将以下内容添加到类型定义中
type JWT @jwt {
roles: [String!]!
}
类型名称 |
@jwtClaim
指令
roles
声明不一定要位于 JWT 负载根目录。它可以位于嵌套位置,例如在 myApplication
下
{
"sub": "user1234",
"myApplication": {
"roles": ["user", "admin"]
}
}
在这种情况下,请将 @jwtClaim
指令与 @jwt
指令一起使用
type JWT @jwt {
roles: [String!]! @jwtClaim(path: "myApplication.roles")
}
此外,嵌套位置的路径中可能包含 .
字符,例如
{
"sub": "user1234",
"http://www.myapplication.com": {
"roles": ["user", "admin"]
}
}
这些字符必须转义
type JWT @jwt {
roles: [String!]! @jwtClaim(path: "http://www\\\\.myapplication\\\\.com.roles")
}
|