授权
非官方测试版翻译
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
createContext 函数会在每个传入请求时被调用,因此您可以在此处通过请求对象添加关于调用用户的上下文信息。
从请求头创建上下文
server/context.tstsimport type {CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';import {decodeAndVerifyJwtToken } from './utils';export async functioncreateContext ({req ,res }:CreateHTTPContextOptions ) {// Create your context based on the request object// Will be available as `ctx` in all your resolvers// This is just an example of something you might want to do in your ctx fnasync functiongetUserFromHeader () {if (req .headers .authorization ) {constuser = awaitdecodeAndVerifyJwtToken (req .headers .authorization .split (' ')[1],);returnuser ;}return null;}constuser = awaitgetUserFromHeader ();return {user ,};}export typeContext =Awaited <ReturnType <typeofcreateContext >>;
server/context.tstsimport type {CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';import {decodeAndVerifyJwtToken } from './utils';export async functioncreateContext ({req ,res }:CreateHTTPContextOptions ) {// Create your context based on the request object// Will be available as `ctx` in all your resolvers// This is just an example of something you might want to do in your ctx fnasync functiongetUserFromHeader () {if (req .headers .authorization ) {constuser = awaitdecodeAndVerifyJwtToken (req .headers .authorization .split (' ')[1],);returnuser ;}return null;}constuser = awaitgetUserFromHeader ();return {user ,};}export typeContext =Awaited <ReturnType <typeofcreateContext >>;
选项一:在解析器中授权
server/routers/_app.tstsimport {initTRPC ,TRPCError } from '@trpc/server';import {z } from 'zod';typeContext = {user : {name : string } | null };export constt =initTRPC .context <Context >().create ();constappRouter =t .router ({// open for anyonehello :t .procedure .input (z .string ().nullish ()).query ((opts ) => `hello ${opts .input ??opts .ctx .user ?.name ?? 'world'}`),// checked in resolversecret :t .procedure .query ((opts ) => {if (!opts .ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}return {secret : 'sauce',};}),});
server/routers/_app.tstsimport {initTRPC ,TRPCError } from '@trpc/server';import {z } from 'zod';typeContext = {user : {name : string } | null };export constt =initTRPC .context <Context >().create ();constappRouter =t .router ({// open for anyonehello :t .procedure .input (z .string ().nullish ()).query ((opts ) => `hello ${opts .input ??opts .ctx .user ?.name ?? 'world'}`),// checked in resolversecret :t .procedure .query ((opts ) => {if (!opts .ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}return {secret : 'sauce',};}),});
选项二:使用中间件授权
server/routers/_app.tstsimport {initTRPC ,TRPCError } from '@trpc/server';import {z } from 'zod';typeContext = {user : {name : string } | null };export constt =initTRPC .context <Context >().create ();// you can reuse this for any procedureexport constprotectedProcedure =t .procedure .use (async functionisAuthed (opts ) {const {ctx } =opts ;// `ctx.user` is nullableif (!ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnopts .next ({ctx : {// ✅ user value is known to be non-null nowuser :ctx .user ,},});},);t .router ({// this is accessible for everyonehello :t .procedure .input (z .string ().nullish ()).query ((opts ) => `hello ${opts .input ??opts .ctx .user ?.name ?? 'world'}`),admin :t .router ({// this is accessible only to adminssecret :protectedProcedure .query ((opts ) => {return {secret : 'sauce',};}),}),});
server/routers/_app.tstsimport {initTRPC ,TRPCError } from '@trpc/server';import {z } from 'zod';typeContext = {user : {name : string } | null };export constt =initTRPC .context <Context >().create ();// you can reuse this for any procedureexport constprotectedProcedure =t .procedure .use (async functionisAuthed (opts ) {const {ctx } =opts ;// `ctx.user` is nullableif (!ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnopts .next ({ctx : {// ✅ user value is known to be non-null nowuser :ctx .user ,},});},);t .router ({// this is accessible for everyonehello :t .procedure .input (z .string ().nullish ()).query ((opts ) => `hello ${opts .input ??opts .ctx .user ?.name ?? 'world'}`),admin :t .router ({// this is accessible only to adminssecret :protectedProcedure .query ((opts ) => {return {secret : 'sauce',};}),}),});