มิดเดิลแวร์และบริบท
เพิ่มการยืนยันตัวตนและบริบทที่ใช้ร่วมกันให้โพรซีเยอร์
มิดเดิลแวร์และบริบท เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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 จะทำงานก่อนตัวแก้ไขของโพรซีเยอร์ โดยสามารถตรวจสอบสิทธิ์ บันทึกเหตุการณ์ หรือแก้ไขบริบทได้ middleware จะเรียก next() เพื่อดำเนินการต่อ หรือโยนข้อผิดพลาดเพื่อปฏิเสธคำขอ
const logger = t.middleware(async ({ path, next }) => {
console.log('calling', path);
return next();
});middleware สำหรับการยืนยันตัวตน
middleware ที่พบได้ทั่วไปใช้บังคับให้มีการยืนยันตัวตน หากไม่มีผู้ใช้ในบริบท middleware จะโยนข้อผิดพลาด UNAUTHORIZED มิฉะนั้นจะดำเนินการต่อไปยังตัวแก้ไข
import { TRPCError } from '@trpc/server';
const isAuthed = t.middleware(({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next();
});การทำให้ประเภทบริบทแคบลงด้วยขั้นตอนถัดไป
middleware สามารถปรับประเภทบริบทให้ละเอียดขึ้นได้ด้วยการส่ง ctx ใหม่ให้กับ next หลังจากตรวจสอบการยืนยันตัวตนแล้ว จะรับประกันได้ว่ามีผู้ใช้อยู่จริง ดังนั้นเราจึงปรับประเภทของ user จากอาจเป็นค่าว่างให้เป็นไม่เป็นค่าว่าง
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);การส่งต่อ ctx ที่มีประเภท
บริบทที่ปรับประเภทให้แคบลงจะถูกส่งต่อไปด้วย เนื่องจาก protectedProcedure รับประกันว่า ctx.user มีอยู่ ตัวแก้ไขทุกตัวที่สร้างจากสิ่งนี้จึงเห็นประเภทที่ไม่เป็นค่าว่างโดยไม่ต้องตรวจสอบซ้ำ middleware จะเข้ารหัสเงื่อนไขคงที่นี้ไว้เพียงครั้งเดียว
// In any protectedProcedure resolver:
// ctx.user is User, not User | nullการประกอบ middleware
ประกอบ middleware ได้ด้วยการเชื่อม .use ต่อกัน คุณอาจใช้การบันทึกเหตุการณ์ก่อน จากนั้นการยืนยันตัวตน แล้วจึงตรวจสอบบทบาท แต่ละส่วนจะทำงานตามลำดับ และแต่ละส่วนสามารถปรับประเภทบริบทให้แคบลงเพิ่มเติมสำหรับส่วนถัดไป
const adminProcedure = protectedProcedure.use(({ ctx, next }) => {
if (ctx.user.role !== 'admin') {
throw new TRPCError({ code: 'FORBIDDEN' });
}
return next();
});ภาพรวมทั้งหมด
บริบทจัดเตรียมข้อมูลต่อคำขอ middleware ป้องกันและปรับประเภทข้อมูลนั้นให้ละเอียดขึ้น และโพรซีเยอร์เฉพาะทางจะฝังการรับประกันเหล่านี้ไว้ เมื่อรวมกับสคีมาอินพุตและ client ที่มีประเภทแล้ว คุณจะได้ API ที่ปลอดภัยทั้งในเวลาทำงาน และ เวลาคอมไพล์ ตั้งแต่ต้นจนจบ
// createContext -> ctx
// middleware -> auth + narrowing
// protectedProcedure -> guaranteed ctx.user
// typed client -> end-to-end safetyตรวจสอบความเข้าใจ
ทดสอบความเข้าใจบริบทและ middleware
ทบทวน
คุณได้รักษาความปลอดภัยให้ API ของ tRPC ด้วยบริบทและ middleware
createContextสร้างข้อมูลร่วมต่อคำขอ โดยกำหนดประเภทผ่านinitTRPC.context- middleware ทำงานก่อนตัวแก้ไขเพื่อป้องกันและปรับบริบทให้ละเอียดขึ้น
- การส่ง
ctxให้กับnextจะทำให้ประเภทของบริบทแคบลง protectedProcedureฝังการยืนยันตัวตนไว้ ทำให้ตัวแก้ไขได้รับผู้ใช้ที่ไม่เป็นค่าว่าง
คุณเรียนจบหลักสูตรความปลอดภัยด้านประเภทตั้งแต่ต้นจนจบแล้ว
คำถามที่พบบ่อย
บทเรียน “มิดเดิลแวร์และบริบท” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “มิดเดิลแวร์และบริบท” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “มิดเดิลแวร์และบริบท”
เพิ่มการยืนยันตัวตนและบริบทที่ใช้ร่วมกันให้โพรซีเยอร์ คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “มิดเดิลแวร์และบริบท” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สถาปัตยกรรม tRPC
- การกำหนดเราเตอร์และโพรซีเยอร์
- การอนุมานชนิดข้อมูลระหว่างไคลเอนต์กับเซิร์ฟเวอร์
- มิดเดิลแวร์และบริบท