chris
chris
TTCTheo's Typesafe Cult
Created by chris on 1/26/2024 in #questions
How to implement Role Based Authorization in T3?
Hey community, I am new to the T3 stack and would like to implement role based authorization in my project. To ensure that only authorized users with the admin role can execute certain queries, I have created a new adminProcedure:
/**
* Admin procedure
*
* Only executes, when the user is authenticated and has the admin role.
*/
export const adminProcedure = t.procedure.use(({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

// Split up for debugging purposes
if (ctx.session.user.role != "ADMIN") {
throw new TRPCError({
code: "UNAUTHORIZED",
message: `No Admin access. Current Role: ${ctx.session.user.role}`,
});
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
},
});
});
/**
* Admin procedure
*
* Only executes, when the user is authenticated and has the admin role.
*/
export const adminProcedure = t.procedure.use(({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

// Split up for debugging purposes
if (ctx.session.user.role != "ADMIN") {
throw new TRPCError({
code: "UNAUTHORIZED",
message: `No Admin access. Current Role: ${ctx.session.user.role}`,
});
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
},
});
});
This works in theory, but somehow the roles of the users are not taken over correctly. My sessionCallback looks like this:
export const authOptions: NextAuthOptions = {
callbacks: {
session: ({ session, user }) => ({
...session,
user: {
...session.user,
role: session.user.role,
id: user.id,
},
}),
},
// ...
}
export const authOptions: NextAuthOptions = {
callbacks: {
session: ({ session, user }) => ({
...session,
user: {
...session.user,
role: session.user.role,
id: user.id,
},
}),
},
// ...
}
In my admin procedure, however, the role value always remains undefined. Does anyone have any idea what I am doing wrong or what I am missing? Thanks in advance!
9 replies