next.js TRPC如何使用服务器客户端动态设置上下文

mwkjh3gx  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(151)

我正在学习tRPC docs如何为服务器端调用创建一个调用者,但是当在NextJS 13页面中使用时,你应该如何动态地设置这个值呢?
这就是我的context.ts的样子:

import { cookies } from "next/headers";
import * as jose from "jose";
import jwt from "jsonwebtoken";
import { inferAsyncReturnType } from "@trpc/server";

interface ContextUser {
    id: number;
    username: string;
    token: string;
}

export async function createContext() {
    async function getUserFromCookie(): Promise<ContextUser | null> {
        var token = cookies().get("jwt");

        if (!token?.value) return null;

        const secret = new TextEncoder().encode(process.env.JWT_SECRET);

        try {
            await jose.jwtVerify(token.value, secret);
        } catch (error) {
            return null;
        }

        const jwtPayload = jwt.decode(token.value) as any;

        return {
            id: jwtPayload.nameid,
            username: jwtPayload.unique_name,
            token: token.value,
        };
    }

    const user = await getUserFromCookie();

    return {
        user,
    };
}

export type Context = inferAsyncReturnType<typeof createContext>;

我有一个中间件来检查用户是否被设置,并导出一个授权的过程:

import { TRPCError, initTRPC } from "@trpc/server";
import { Context } from "./context";

const t = initTRPC.context<Context>().create();

export const router = t.router;
export const publicProcedure = t.procedure;

const authorised = t.middleware(async ({ ctx, next }) => {
    if (!ctx.user) throw new TRPCError({ code: "UNAUTHORIZED" });

    return next();
});

export const authorisedProcedure = t.procedure.use(authorised);

在我的server.ts中,我导出一个服务器客户端,如下所示:

import { appRouter } from "@/server";

export const trpcServerClient = appRouter.createCaller({
    user: { id: 1, username: "foo", token: "bar" },
});

当我使用带有有效cookie的trpcServerClient调用一个过程时,我可以通过调试createContext来看到令牌存在并且它设置了上下文,但是在过程中,ctx将是user: { id: 1, username: "foo", token: "bar" }
那么我的问题是,当你必须在createCaller函数中为你的上下文传递一个值时,你应该如何在使用服务器客户端时动态地设置上下文呢?

pcww981p

pcww981p1#

import { createContext } from "@/server/context"
import { appRouter } from "@/server";

export const trpcServerClient = appRouter.createCaller(await createContext());

(note如果你还在使用“es5”,在顶层使用await可能需要改变你的tsconfig目标)

相关问题