mirror of
https://github.com/ArthurDanjou/trpc-nuxt.git
synced 2026-01-14 12:14:40 +01:00
docs: add auth tips
This commit is contained in:
104
docs/content/1.get-started/3.tips/4.authorization.md
Normal file
104
docs/content/1.get-started/3.tips/4.authorization.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
title: Authorization
|
||||
---
|
||||
|
||||
# Authorization
|
||||
|
||||
The `createContext` function is called for each incoming request so here you can add contextual information about the calling user from the request object.
|
||||
|
||||
## Create context from request headers
|
||||
|
||||
```ts [server/trpc/context.ts]
|
||||
import type { H3Event } from 'h3'
|
||||
import { inferAsyncReturnType } from '@trpc/server'
|
||||
import { decodeAndVerifyJwtToken } from './somewhere/in/your/app/utils'
|
||||
|
||||
export async function createContext({
|
||||
req,
|
||||
res,
|
||||
}: H3Event) {
|
||||
// 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 fn
|
||||
async function getUserFromHeader() {
|
||||
if (req.headers.authorization) {
|
||||
const user = await decodeAndVerifyJwtToken(
|
||||
req.headers.authorization.split(' ')[1],
|
||||
)
|
||||
return user
|
||||
}
|
||||
return null
|
||||
}
|
||||
const user = await getUserFromHeader()
|
||||
|
||||
return {
|
||||
user,
|
||||
}
|
||||
}
|
||||
type Context = inferAsyncReturnType<typeof createContext>
|
||||
```
|
||||
|
||||
## Option 1: Authorize using resolver
|
||||
|
||||
```ts
|
||||
import { TRPCError, initTRPC } from '@trpc/server'
|
||||
import type { Context } from '../context'
|
||||
|
||||
export const t = initTRPC.context<Context>().create()
|
||||
|
||||
const appRouter = t.router({
|
||||
// open for anyone
|
||||
hello: t.procedure
|
||||
.input(z.string().nullish())
|
||||
.query(({ input, ctx }) => `hello ${input ?? ctx.user?.name ?? 'world'}`),
|
||||
// checked in resolver
|
||||
secret: t.procedure.query(({ ctx }) => {
|
||||
if (!ctx.user) {
|
||||
throw new TRPCError({ code: 'UNAUTHORIZED' })
|
||||
}
|
||||
return {
|
||||
secret: 'sauce',
|
||||
}
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
## Option 2: Authorize using middleware
|
||||
|
||||
```ts
|
||||
import { TRPCError, initTRPC } from '@trpc/server'
|
||||
|
||||
export const t = initTRPC.context<Context>().create()
|
||||
|
||||
const isAuthed = t.middleware(({ next, ctx }) => {
|
||||
if (!ctx.user?.isAdmin) {
|
||||
throw new TRPCError({ code: 'UNAUTHORIZED' })
|
||||
}
|
||||
return next({
|
||||
ctx: {
|
||||
user: ctx.user,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// you can reuse this for any procedure
|
||||
export const protectedProcedure = t.procedure.use(isAuthed)
|
||||
|
||||
t.router({
|
||||
// this is accessible for everyone
|
||||
hello: t.procedure
|
||||
.input(z.string().nullish())
|
||||
.query(({ input, ctx }) => `hello ${input ?? ctx.user?.name ?? 'world'}`),
|
||||
admin: t.router({
|
||||
// this is accessible only to admins
|
||||
secret: protectedProcedure.query(({ ctx }) => {
|
||||
return {
|
||||
secret: 'sauce',
|
||||
}
|
||||
}),
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
This page is entirely based on [authorization docs](https://trpc.io/docs/v10/authorization) of tRPC with a minimal change made to work with Nuxt.
|
||||
Reference in New Issue
Block a user