TypeScript Academy · Урок

Промежуточное ПО и контекст

Добавляйте авторизацию и общий контекст к процедурам

Урок 4 из 413 шагов

«Промежуточное ПО и контекст» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.

Что такое контекст

Каждый запрос tRPC содержит контекст: общие данные, доступные всем процедурам, например client базы данных, запрос и текущий пользователь. Контекст создаётся один раз для каждого запроса с помощью функции createContext.

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

Типизация контекста

tRPC выводит тип контекста из createContext и передаёт его через каждую процедуру. Вы инициализируете экземпляр этим типом контекста, чтобы обработчики видели ctx с правильной типизацией.

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

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

Чтение контекста в обработчике

Внутри любой процедуры контекст доступен как ctx и полностью типизирован. Здесь процедура получает текущего пользователя из контекста.

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

Что такое middleware

Middleware выполняется до обработчика процедуры. Он может проверять права, выполнять log или изменять контекст. Middleware либо вызывает next(), чтобы продолжить выполнение, либо выбрасывает ошибку и отклоняет запрос.

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

Middleware аутентификации

Распространённый middleware обеспечивает аутентификацию. Если в контексте нет пользователя, он выбрасывает ошибку UNAUTHORIZED; в противном случае передаёт управление обработчику.

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

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

Уточнение контекста с помощью next

Middleware может уточнить тип контекста, передав новый ctx в next. После проверки аутентификации наличие пользователя гарантировано, поэтому его тип сужается от допускающего отсутствие значения до не допускающего его.

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

Создание защищённой процедуры

Подключите middleware с помощью .use, чтобы создать повторно используемую защищённую процедуру. Любая процедура, созданная на её основе, требует аутентификации и видит пользователя, наличие которого гарантировано.

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

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

Открытые и защищённые процедуры

Теперь у Вас есть два строительных блока: publicProcedure для открытых конечных точек и protectedProcedure для конечных точек, требующих аутентификации. Правильный выбор основы документирует и обеспечивает контроль доступа на уровне типов и во время выполнения.

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

Передача типизированного контекста

Уточнённый контекст передаётся дальше: поскольку protectedProcedure гарантирует наличие ctx.user, каждый созданный на его основе обработчик видит тип пользователя без повторной проверки. Middleware единожды кодирует это неизменное условие.

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

Композиция middleware

Middleware объединяются в цепочку с помощью .use. Можно сначала применить журналирование, затем аутентификацию, а после этого проверку роли. Каждый middleware выполняется по порядку и может дополнительно уточнить контекст для следующего.

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

Полная картина

Контекст предоставляет данные для каждого запроса, middleware защищает и уточняет их, а специализированные процедуры встраивают эти гарантии. В сочетании со схемами входных данных и типизированным client Вы получаете программный интерфейс, безопасный и во время выполнения, и во время компиляции — от начала до конца.

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

Проверьте себя

Проверьте, насколько хорошо Вы поняли контекст и middleware.

Повторение

Вы защитили программный интерфейс tRPC с помощью контекста и middleware.

  • createContext создаёт общие данные для каждого запроса, типизированные с помощью initTRPC.context.
  • Middleware выполняется до обработчиков, чтобы защищать и уточнять контекст.
  • Передача ctx в next уточняет его тип.
  • protectedProcedure встраивает аутентификацию, поэтому обработчики получают пользователя, наличие которого гарантировано.

Вы завершили курс по сквозной безопасности типов.

Можно начать бесплатно

Изучай TypeScript с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
101
Уроки
352

Часто задаваемые вопросы

Урок «Промежуточное ПО и контекст» бесплатный?

Да — полный текст урока «Промежуточное ПО и контекст» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Промежуточное ПО и контекст»?

Добавляйте авторизацию и общий контекст к процедурам Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать TypeScript Academy?

Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Промежуточное ПО и контекст»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке TypeScript Academy?

Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Архитектура tRPC
  2. Определение маршрутизаторов и процедур
  3. Вывод типов на стороне клиента и сервера
  4. Промежуточное ПО и контекст
← Назад к TypeScript Academy