0Pricing
TypeScript Academy · Lekcja

Middleware i kontekst

Dodawaj uwierzytelnianie i współdzielony kontekst do procedur

Middleware i kontekst to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 4 lekcji w sumie.

Czym jest kontekst

Każde żądanie tRPC przenosi kontekst: współdzielone dane dostępne dla wszystkich procedur, takie jak klient bazy danych, żądanie i bieżący użytkownik. Kontekst jest tworzony raz dla każdego żądania za pomocą funkcji createContext.

export async function createContext({ req }: { req: Request }) {
  const token = req.headers.get('authorization');
  const user = await getUserFromToken(token);
  return { user };
}

Typowanie kontekstu

tRPC wyprowadza typ kontekstu na podstawie createContext i przekazuje go do każdej procedury. Instancję inicjalizuje się z tym typem kontekstu, aby resolvery widziały poprawnie typowane ctx.

import { initTRPC } from '@trpc/server';

type Context = Awaited<ReturnType<typeof createContext>>;
const t = initTRPC.context<Context>().create();

Odczytywanie ctx w resolverze

Wewnątrz każdej procedury kontekst jest dostępny jako ctx i jest w pełni typowany. W tym przypadku procedura odczytuje bieżącego użytkownika z kontekstu.

const me = t.procedure.query(({ ctx }) => {
  // ctx.user is typed from createContext
  return ctx.user;
});

Czym jest middleware

Middleware uruchamia się przed resolverem procedury. Może sprawdzać uprawnienia, rejestrować zdarzenia lub modyfikować kontekst. Aby kontynuować, wywołuje next(), a w celu odrzucenia żądania zgłasza wyjątek.

const logger = t.middleware(async ({ path, next }) => {
  console.log('calling', path);
  return next();
});

Middleware uwierzytelniania

Typowe middleware wymusza uwierzytelnianie. Jeśli w kontekście nie ma użytkownika, zgłasza błąd UNAUTHORIZED; w przeciwnym razie przekazuje wykonanie do resolvera.

import { TRPCError } from '@trpc/server';

const isAuthed = t.middleware(({ ctx, next }) => {
  if (!ctx.user) {
    throw new TRPCError({ code: 'UNAUTHORIZED' });
  }
  return next();
});

Zawężanie kontekstu za pomocą next

Middleware może doprecyzować typ kontekstu, przekazując nowy element ctx do next. Po sprawdzeniu uwierzytelnienia wiadomo, że użytkownik istnieje, dlatego zawężamy typ user z potencjalnie pustego do niepustego.

const isAuthed = t.middleware(({ ctx, next }) => {
  if (!ctx.user) throw new TRPCError({ code: 'UNAUTHORIZED' });
  return next({ ctx: { user: ctx.user } }); // user now non-null
});

Budowanie chronionej procedury

Dołącz middleware za pomocą .use, aby utworzyć wielokrotnego użytku chronioną procedurę. Każda procedura zbudowana na jej podstawie wymaga uwierzytelnienia i widzi użytkownika, który na pewno istnieje.

export const protectedProcedure = t.procedure.use(isAuthed);

const secret = protectedProcedure.query(({ ctx }) => {
  return 'Hello ' + ctx.user.name; // user is guaranteed
});

Publiczne a chronione

Mają Państwo teraz dwa elementy budulcowe: publicProcedure dla otwartych endpointów oraz protectedProcedure dla endpointów wymagających uwierzytelnienia. Wybór właściwej podstawy dokumentuje i egzekwuje dostęp zarówno na poziomie typów, jak i w czasie wykonywania.

const ping = publicProcedure.query(() => 'pong');
const account = protectedProcedure.query(({ ctx }) => ctx.user);

Propagacja typowanego ctx

Zawężony kontekst jest propagowany dalej: ponieważ protectedProcedure gwarantuje obecność ctx.user, każdy zbudowany na niej resolver widzi typ niepusty bez ponownego sprawdzania. Middleware koduje ten niezmiennik tylko raz.

// In any protectedProcedure resolver:
// ctx.user is User, not User | null

Składanie middleware

Middleware składa się przez łańcuch wywołań .use. Można najpierw zastosować rejestrowanie zdarzeń, następnie uwierzytelnianie, a potem sprawdzanie roli. Każdy element uruchamia się w odpowiedniej kolejności i może dodatkowo zawęzić kontekst dla następnego.

const adminProcedure = protectedProcedure.use(({ ctx, next }) => {
  if (ctx.user.role !== 'admin') {
    throw new TRPCError({ code: 'FORBIDDEN' });
  }
  return next();
});

Pełny obraz

Kontekst dostarcza danych właściwych dla żądania, middleware chroni je i doprecyzowuje, a wyspecjalizowane procedury utrwalają te gwarancje. W połączeniu ze schematami danych wejściowych i typowanym klientem otrzymuje się interfejs API bezpieczny zarówno w czasie wykonywania, jak i kompilacji — od początku do końca.

// createContext -> ctx
// middleware -> auth + narrowing
// protectedProcedure -> guaranteed ctx.user
// typed client -> end-to-end safety

Szybkie sprawdzenie

Proszę sprawdzić swoje rozumienie kontekstu i middleware.

Podsumowanie

Zabezpieczyli Państwo API tRPC za pomocą kontekstu i middleware.

  • createContext tworzy współdzielone dane dla każdego żądania, typowane za pomocą initTRPC.context.
  • Middleware uruchamia się przed resolverami, aby chronić i doprecyzowywać kontekst.
  • Przekazanie ctx do next zawęża jego typ.
  • protectedProcedure utrwala uwierzytelnianie, dzięki czemu resolvery otrzymują użytkownika, który na pewno istnieje.

Ukończyli Państwo kurs bezpieczeństwa typów end-to-end.

Często zadawane pytania

Czy lekcja „Middleware i kontekst” jest bezpłatna?

Tak — pełny tekst „Middleware i kontekst” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Middleware i kontekst”?

Dodawaj uwierzytelnianie i współdzielony kontekst do procedur Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?

Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Middleware i kontekst”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?

Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Architektura tRPC
  2. Definiowanie routerów i procedur
  3. Wnioskowanie typów po stronie klienta i serwera
  4. Middleware i kontekst
← Powrót do TypeScript Academy