😎

【tRPC】NextJs & tRPC 【#6 tRPC Authorization2 Create ProtectedProcedure】

に公開

【#6 tRPC Authorization2 Create ProtectedProcedure】

YouTube: https://youtu.be/u5tguOViClQ
https://youtu.be/u5tguOViClQ

今回はtRPC側の認証機能の設定を進めていきます。

https://trpc.io/docs/server/authorization

各個別のルートで認証のチェックを行う方法と
ミドルウェアを設定してチェックを行う方法があります。

コメントアウトは
各個別のルートで認証のチェックを行う方法です。

src/trpc/routers/_app.ts
import { z } from 'zod'
// import { auth } from '@clerk/nextjs/server'

// import { TRPCError } from '@trpc/server'
import { baseProcedure, createTRPCRouter, protectedProcedure } from '../init'

export const appRouter = createTRPCRouter({
  hello: protectedProcedure
    .input(
      z.object({
        text: z.string(),
      })
    )
    .query(async (opts) => {
      // const { userId } = await auth()

      // if (!userId) {
      //   throw new TRPCError({ code: 'UNAUTHORIZED' })
      // }

      return {
        greeting: `hello ${opts.input.text}`,
      }
    }),
})
// export type definition of API
export type AppRouter = typeof appRouter
src/trpc/init.ts
import { auth } from '@clerk/nextjs/server'
import { initTRPC, TRPCError } from '@trpc/server'
import { cache } from 'react'

export const createTRPCContext = cache(async () => {
  const { userId } = await auth()

  return { clerkUserId: userId }
})

export type Context = Awaited<ReturnType<typeof createTRPCContext>>
// Avoid exporting the entire t-object
// since it's not very descriptive.
// For instance, the use of a t variable
// is common in i18n libraries.
const t = initTRPC.context<Context>().create({
  /**
   * @see https://trpc.io/docs/server/data-transformers
   */
  // transformer: superjson,
})
// Base router and procedure helpers
export const createTRPCRouter = t.router
export const createCallerFactory = t.createCallerFactory
export const baseProcedure = t.procedure
export const protectedProcedure = t.procedure.use(async function isAuthed(
  opts
) {
  const { ctx } = opts

  if (!ctx.clerkUserId) {
    throw new TRPCError({ code: 'UNAUTHORIZED' })
  }

  return opts.next({
    ctx: {
      ...ctx,
      userId: ctx.clerkUserId,
    },
  })
})

Discussion