如何将 Auth0 的 ID 令牌转发到 GraphQL 代码生成器?
Posted
技术标签:
【中文标题】如何将 Auth0 的 ID 令牌转发到 GraphQL 代码生成器?【英文标题】:How to forward Auth0's ID token to GraphQL Code Generator? 【发布时间】:2021-11-17 02:05:52 【问题描述】:我正在使用带有 React Query 的 GraphQL 代码生成器,这是我的 codegen.yml
:
overwrite: true
schema: http://localhost:4000/graphql
generates:
src/lib/__generated__/graphql.ts:
documents:
- "**/graphql/**/*.graphql"
- "!mysqldata/**"
plugins:
- add:
content: &comment "/* DO NOT EDIT! this file was generated by graphql-codegen */\n/* eslint-disable */"
- add:
placement: append
content: "export fetcher "
- typescript
- typescript-operations
- typescript-react-query
config:
fetcher:
endpoint: "`$process.env.NEXT_PUBLIC_API_URL/graphql`"
fetchParams:
credentials: include
headers:
Content-Type: application/json
这会生成以下提取器:
function fetcher<TData, TVariables>(query: string, variables?: TVariables)
return async (): Promise<TData> =>
const res = await fetch(`$process.env.NEXT_PUBLIC_API_URL/graphql` as string,
method: "POST",
credentials: "include",
headers: "Content-Type":"application/json",
body: JSON.stringify( query, variables ),
);
const json = await res.json();
if (json.errors)
const message = json.errors[0];
throw new Error(message);
return json.data;
NEXT_PUBLIC_API_URL
指的是外部 GraphQL API。
在我的 Next.js 应用程序中,我尝试使用 nextjs-auth0 和 auth0-react。
nextjs-auth0
允许我从 Next.js API 路由访问 Auth0 的 ID 令牌:
export default (req: NextApiRequest, res: NextApiResponse) =>
const session = getSession(req, res)
const idToken = session?.idToken
而auth0-react
允许我获取令牌客户端:
const claims = await auth0.getIdTokenClaims();
const idToken = claims.__raw;
问题在于,由于这些抽象,我无法找到一种方法将此令牌包含在对我的 GraphQL 端点的请求中,例如:
headers:
authorization: `Bearer $session?.idToken`,
,
【问题讨论】:
【参考方案1】:在我发布了feature request 以在 cookie 中包含 ID 令牌后,我发现 nextjs-auth0
设置的“appSession”cookie 是包含 ID 令牌的加密令牌,我使用 @ 实现了自定义服务器逻辑987654323@源码作为参考:
type DecodedToken = Record<"idToken" | "token_type", string>
const API_BASE_URL = "https://example.com"
const BYTE_LENGTH = 32
const ENCRYPTION_INFO = "JWE CEK"
const HASH = "SHA-256"
const alg = "dir"
const enc = "A256GCM"
/**
* Derives appropriate sized keys from provided secret random string/passphrase using
* HKDF (HMAC-based Extract-and-Expand Key Derivation Function) defined in RFC 8569
* @see https://tools.ietf.org/html/rfc5869
*/
function deriveKey(secret: string)
return hkdf(secret, BYTE_LENGTH, info: ENCRYPTION_INFO, hash: HASH )
export const meQueryField = queryField("me",
type: "User",
async resolve(_, __, ctx)
const jwe = ctx.request.cookies["appSession"]
if (!jwe)
return null
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const octKey = JWK.asKey(deriveKey(process.env["AUTH0_SECRET"]!))
const cleartext = JWE.decrypt(jwe, octKey,
complete: true,
contentEncryptionAlgorithms: [alg],
keyManagementAlgorithms: [enc],
)
const idToken, token_type: tokenType = JSON.parse(
cleartext.toString()
) as DecodedToken
const response = await fetch(`$API_BASE_URL/users/me`,
headers:
Authorization: `$tokenType $idToken`,
,
)
const user = (await response.json()) as Response
return
id: user.data.id,
...
,
)
它不漂亮,但它有效。 AUTH0_SECRET
与 nextjs-auth0
中用于加密令牌的密钥相同
【讨论】:
请考虑将您的答案标记为解决方案(一旦可能)。以上是关于如何将 Auth0 的 ID 令牌转发到 GraphQL 代码生成器?的主要内容,如果未能解决你的问题,请参考以下文章
我应该将 id 令牌从我的 SPA 发送到我的 rest 后端吗?